欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android 架構(gòu)之?dāng)?shù)據(jù)庫框架升級

 更新時(shí)間:2021年09月23日 14:10:08   作者:hqk  
上一篇講解了# Android 架構(gòu)之?dāng)?shù)據(jù)框架搭建 ,里面含有數(shù)據(jù)庫最基礎(chǔ)的增刪改查功能,不過只考慮了單數(shù)據(jù)庫,開發(fā)者可以舉一反三按照對應(yīng)思路設(shè)計(jì)多數(shù)據(jù)庫架構(gòu)。 在本篇里,將會(huì)講解令開發(fā)者比較頭疼的數(shù)據(jù)庫升級,需要的朋友可以參考下面文章內(nèi)容

前言:

上一篇講解了Android 架構(gòu)之?dāng)?shù)據(jù)框架搭建 ,里面含有數(shù)據(jù)庫最基礎(chǔ)的增刪改查功能,不過只考慮了單數(shù)據(jù)庫,開發(fā)者可以舉一反三按照對應(yīng)思路設(shè)計(jì)多數(shù)據(jù)庫架構(gòu)。 在本篇里,將會(huì)講解令開發(fā)者比較頭疼的數(shù)據(jù)庫升級。

話不多說,先來看代碼效果,看看是否是想要的

如上圖所示:

  • 當(dāng)前APP版本號(hào)為V007;
  • V001、V002升級到V007有對應(yīng)的處理邏輯;
  • V003、V004、V005、V006升級到V007也有對應(yīng)的處理邏輯;
  • 同理可實(shí)現(xiàn)任意版本可闊多個(gè)版本升級到最新數(shù)據(jù)庫;

開始之前我們先理一下數(shù)據(jù)庫升級的邏輯

  1. 任何數(shù)據(jù)庫在操作之前,我們最好有一個(gè)數(shù)據(jù)庫備份,所以這里得要備份對應(yīng)的數(shù)據(jù)庫File文件;
  2. 任何數(shù)據(jù)表在操作之前,也要有一個(gè)數(shù)據(jù)表備份,所以這里會(huì)在原表名加前后綴操作;
  3. 在數(shù)據(jù)表升級的時(shí)候,有些時(shí)候可能會(huì)對表名、表列做任意增刪改的操作,所以這里每次都要?jiǎng)?chuàng)建一個(gè)全新的表;
  4. 全新表創(chuàng)建好了,但是一張空表,這里就需要查詢對應(yīng)加了前后綴的原表數(shù)據(jù),將對應(yīng)數(shù)據(jù)添加至新表里;
  5. 數(shù)據(jù)全部拷貝完成時(shí),為了讓用戶有良好的體驗(yàn),我們需要?jiǎng)h除對應(yīng)加了前后綴的原表;
  6. 對應(yīng)原表刪除完畢時(shí),我們需要?jiǎng)h除對應(yīng)備份數(shù)據(jù)庫的File文件。

總結(jié):

  • 操作【1】和【6】 這倆操作 屬于 java代碼執(zhí)行
  • 其他【2】、【3】、【4】、【5】 這些操作,都屬于SQL操作
  • 但SQL操作,通過效果圖發(fā)現(xiàn),是寫在XML文件里面的,所以需要寫一個(gè)XML解析器

現(xiàn)在我們就按照對應(yīng)步驟一一講解

1、備份原數(shù)據(jù)庫File文件

    /**
     * 復(fù)制單個(gè)文件(可更名復(fù)制)
     *
     * @param oldPathFile 準(zhǔn)備復(fù)制的文件源
     * @param newPathFile 拷貝到新絕對路徑帶文件名(注:目錄路徑需帶文件名)
     * @return
     */
    public static void CopySingleFile(String oldPathFile, String newPathFile) {
        try {
//            int bytesum = 0;
            int byteread = 0;
            File oldfile = new File(oldPathFile);
            File newFile = new File(newPathFile);
            File parentFile = newFile.getParentFile();
            if (!parentFile.exists()) {
                parentFile.mkdirs();
            }
            if (oldfile.exists()) { //文件存在時(shí)
                InputStream inStream = new FileInputStream(oldPathFile); //讀入原文件
                FileOutputStream fs = new FileOutputStream(newPathFile);
                byte[] buffer = new byte[1024];
                while ((byteread = inStream.read(buffer)) != -1) {
//                    bytesum += byteread; //字節(jié)數(shù) 文件大小
                    fs.write(buffer, 0, byteread);
                }
                inStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

總結(jié):這也沒啥可說的,就一個(gè)很簡單的文件復(fù)制。

2、數(shù)據(jù)庫升級XML編寫 updateXml.xml

<?xml version="1.0" encoding="utf-8"?>
<updateXml>
    <createVersion version="V007">
        <createDb name="hqk">  <!-- 要升級數(shù)據(jù)庫對應(yīng)名 ,如果應(yīng)用含多個(gè)數(shù)據(jù)庫,那么可以創(chuàng)建多個(gè) createDb 標(biāo)簽-->
            <sql_createTable>  <!-- 創(chuàng)建最新的表結(jié)構(gòu) -->
                <!--
                     @DbFiled("time")
                    private  String time;
                    @DbFiled("id")
                    private  Long id;
                    @DbFiled("path")
                    private  String path;
                 -->
                create table if not exists tb_photo ( id Long,tb_time TEXT ,tb_path TEXT,tb_name TEXT);
            </sql_createTable>
        </createDb>
    </createVersion>

    <!-- V001,V002對應(yīng)版本的app升級到 最新V007版本的升級邏輯-->
    <updateStep versionFrom="V001,V002" versionTo="V007">
        <!-- 對應(yīng)數(shù)據(jù)升級邏輯,對應(yīng)上面的 createDb 標(biāo)簽name ,如果有多對 createDb,這里也可執(zhí)行多對 updateDb-->
        <updateDb name="hqk">
            <sql_before> <!-- 將V001,V002對應(yīng)的舊表重命名備份-->
                alter table tb_photo rename to bak_tb_photo;
            </sql_before>
            <sql_after>  <!-- 查詢重命名后舊表數(shù)據(jù),將對應(yīng)數(shù)據(jù)添加至新表里-->
                insert into tb_photo(tb_time,id, tb_path) select tb_time,tb_id,tb_path from bak_tb_photo;
            </sql_after>
            <sql_after><!-- 刪除舊表備份-->
                drop table if exists bak_tb_photo;
            </sql_after>
        </updateDb>
    </updateStep>

    <updateStep versionFrom="V003,V004,V005,V006" versionTo="V007">
        <updateDb name="hqk">
            <sql_before>
                alter table tb_photo rename to bak_tb_photo;
            </sql_before>
            <sql_after>
                insert into tb_photo(tb_time,id, tb_path) select tb_time,tb_id,tb_path from
                bak_tb_photo;
            </sql_after>

            <sql_after>
                drop table if exists bak_tb_photo;
            </sql_after>
        </updateDb>

    </updateStep>


</updateXml>

總結(jié):

  • createVersion 標(biāo)簽 ,表示 當(dāng)前 最新APP版本需要操作的內(nèi)容
  • createDb 標(biāo)簽,表示當(dāng)前最新對應(yīng)的數(shù)據(jù)庫要操作的內(nèi)容,可多組標(biāo)簽,實(shí)現(xiàn)多個(gè)數(shù)據(jù)庫升級
  • sql_createTable 標(biāo)簽,表示當(dāng)前最新對應(yīng)的數(shù)據(jù)表要操作的內(nèi)容,可多組標(biāo)簽,實(shí)現(xiàn)多表升級
  • updateStep 標(biāo)簽,表示不同版本要升級的對象,可多組標(biāo)簽,達(dá)到不同版本數(shù)據(jù)庫升級到最新數(shù)據(jù)庫的效果
  • updateDb 標(biāo)簽,表示舊版本要修改的對應(yīng)數(shù)據(jù)庫
  • sql_before 標(biāo)簽,表示數(shù)據(jù)庫升級時(shí)優(yōu)先級最高的SQL,(在新表創(chuàng)建前執(zhí)行)
  • sql_after 標(biāo)簽,表示數(shù)據(jù)庫升級時(shí)優(yōu)先級最低并按順序執(zhí)行的SQL(在新表創(chuàng)建后執(zhí)行)

3、創(chuàng)建XML解析器

3.1 對應(yīng)工具類 DomUtils.class

public class DomUtils {
    /**
     * 讀取升級xml
     *
     * @param context
     * @return
     */
    public static UpdateDbXml readDbXml(Context context) {
        InputStream is = null;
        Document document = null;
        try {
            is = context.getAssets().open("updateXml.xml");
            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            document = builder.parse(is);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        if (document == null) {
            return null;
        }

        UpdateDbXml xml = new UpdateDbXml(document);

        return xml;
    }
    /**
     * 新表插入數(shù)據(jù)
     *
     * @param xml
     * @param lastVersion 上個(gè)版本
     * @param thisVersion 當(dāng)前版本
     * @return
     */
    public static UpdateStep findStepByVersion(UpdateDbXml xml, String lastVersion, String thisVersion) {
        if (lastVersion == null || thisVersion == null) {
            return null;
        }
        // 更新腳本
        UpdateStep thisStep = null;
        if (xml == null) {
            return null;
        }
        List<UpdateStep> steps = xml.getUpdateSteps();
        if (steps == null || steps.size() == 0) {
            return null;
        }

        for (UpdateStep step : steps) {
            if (step.getVersionFrom() == null || step.getVersionTo() == null) {
            } else {
                // 升級來源以逗號(hào)分隔
                String[] lastVersionArray = step.getVersionFrom().split(",");
                if (lastVersionArray != null && lastVersionArray.length > 0) {
                    for (int i = 0; i < lastVersionArray.length; i++) {
                        // 有一個(gè)配到update節(jié)點(diǎn)即升級數(shù)據(jù)
                        if (lastVersion.equalsIgnoreCase(lastVersionArray[i]) && step.getVersionTo().equalsIgnoreCase(thisVersion)) {
                            thisStep = step;
                            break;
                        }
                    }
                }
            }
        }
        return thisStep;
    }

    /**
     * 解析出對應(yīng)版本的建表腳本
     *
     * @return
     */
    public static CreateVersion findCreateByVersion(UpdateDbXml xml, String version) {
        CreateVersion cv = null;
        if (xml == null || version == null) {
            return cv;
        }
        List<CreateVersion> createVersions = xml.getCreateVersions();

        if (createVersions != null) {
            for (CreateVersion item : createVersions) {
                Log.i("david", "item=" + item.toString());
                // 如果表相同則要支持xml中逗號(hào)分隔
                String[] createVersion = item.getVersion().trim().split(",");
                for (int i = 0; i < createVersion.length; i++) {
                    if (createVersion[i].trim().equalsIgnoreCase(version)) {
                        cv = item;
                        break;
                    }
                }
            }
        }
        return cv;
    }

}

3.2 對應(yīng)XML的實(shí)體類

UpdateDbXml

/**
 * @ClassName: UpdateDbXml
 * @Description: 升級更新數(shù)據(jù)庫
 *
 */
public class UpdateDbXml {
    /**
     * 升級腳本列表
     */
    private List<UpdateStep> updateSteps;
    /**
     * 升級版本
     */
    private List<CreateVersion> createVersions;

    public UpdateDbXml(Document document) {
        {
            // 獲取升級腳本
            NodeList updateSteps = document.getElementsByTagName("updateStep");
            this.updateSteps = new ArrayList<UpdateStep>();
            for (int i = 0; i < updateSteps.getLength(); i++) {
                Element ele = (Element) (updateSteps.item(i));
                Log.i("jett","updateSteps 各個(gè)升級的版本:"+ele.toString());
                UpdateStep step = new UpdateStep(ele);
                this.updateSteps.add(step);
            }
        }
        {
            /**
             * 獲取各升級版本
             */
            NodeList createVersions = document.getElementsByTagName("createVersion");
            this.createVersions = new ArrayList<CreateVersion>();
            for (int i = 0; i < createVersions.getLength(); i++) {
                Element ele = (Element) (createVersions.item(i));
                Log.i("jett","各個(gè)升級的版本:"+ele.toString());
                CreateVersion cv = new CreateVersion(ele);
                this.createVersions.add(cv);
            }
        }
    }

    public List<UpdateStep> getUpdateSteps() {
        return updateSteps;
    }

    public void setUpdateSteps(List<UpdateStep> updateSteps) {
        this.updateSteps = updateSteps;
    }

    public List<CreateVersion> getCreateVersions() {
        return createVersions;
    }

    public void setCreateVersions(List<CreateVersion> createVersions) {
        this.createVersions = createVersions;
    }

}

UpdateStep.class

/**
 * @ClassName: UpdateStep
 * @Description: 數(shù)據(jù)庫升級腳本信息
 */
public class UpdateStep
{
 /**
  * 舊版本
  */
 private String versionFrom;

 /**
  * 新版本
  */
 private String versionTo;

 /**
  * 更新數(shù)據(jù)庫腳本
  */
 private List<UpdateDb> updateDbs;

 // ==================================================

 public UpdateStep(Element ele)
 {
  versionFrom = ele.getAttribute("versionFrom");
  versionTo = ele.getAttribute("versionTo");
  updateDbs = new ArrayList<UpdateDb>();

  NodeList dbs = ele.getElementsByTagName("updateDb");
  for (int i = 0; i < dbs.getLength(); i++)
  {
   Element db = (Element) (dbs.item(i));
   UpdateDb updateDb = new UpdateDb(db);
   this.updateDbs.add(updateDb);
  }
 }

 public List<UpdateDb> getUpdateDbs()
 {
  return updateDbs;
 }

 public void setUpdateDbs(List<UpdateDb> updateDbs)
 {
  this.updateDbs = updateDbs;
 }

 public String getVersionFrom()
 {
  return versionFrom;
 }

 public void setVersionFrom(String versionFrom)
 {
  this.versionFrom = versionFrom;
 }

 public String getVersionTo()
 {
  return versionTo;
 }

 public void setVersionTo(String versionTo)
 {
  this.versionTo = versionTo;
 }

}

UpdateDb.class

**
 * @ClassName: UpdateDb
 * @Description: 更新數(shù)據(jù)庫腳本
 *
 */
public class UpdateDb
{
 /**
  * 數(shù)據(jù)庫名稱
  */
 private String dbName;
 /**
  * 
  */
 private List<String> sqlBefores;
 /**
  * 
  */
 private List<String> sqlAfters;

 public UpdateDb(Element ele)
 {
  dbName = ele.getAttribute("name");
  sqlBefores = new ArrayList<String>();
  sqlAfters = new ArrayList<String>();

  {
   NodeList sqls = ele.getElementsByTagName("sql_before");
   for (int i = 0; i < sqls.getLength(); i++)
   {
    String sql_before = sqls.item(i).getTextContent();
    this.sqlBefores.add(sql_before);
   }
  }

  {
   NodeList sqls = ele.getElementsByTagName("sql_after");
   for (int i = 0; i < sqls.getLength(); i++)
   {
    String sql_after = sqls.item(i).getTextContent();
    this.sqlAfters.add(sql_after);
   }
  }

 }

 public String getName()
 {
  return dbName;
 }

 public void setDbName(String dbName)
 {
  this.dbName = dbName;
 }

 public List<String> getSqlBefores()
 {
  return sqlBefores;
 }

 public void setSqlBefores(List<String> sqlBefores)
 {
  this.sqlBefores = sqlBefores;
 }

 public List<String> getSqlAfters()
 {
  return sqlAfters;
 }

 public void setSqlAfters(List<String> sqlAfters)
 {
  this.sqlAfters = sqlAfters;
 }
}

CreateVersion.class

public class CreateVersion
{
 /**
  * 版本信息
  */
 private String version;

 /**
  * 創(chuàng)建數(shù)據(jù)庫表腳本
  */
 private List<CreateDb> createDbs;

 public CreateVersion(Element ele)
 {
  version = ele.getAttribute("version");
  Log.i("jett","CreateVersion="+version);
  {
   createDbs = new ArrayList<CreateDb>();
   NodeList cs = ele.getElementsByTagName("createDb");
   for (int i = 0; i < cs.getLength(); i++)
   {
    Element ci = (Element) (cs.item(i));
    CreateDb cd = new CreateDb(ci);
    this.createDbs.add(cd);
   }
  }
 }

 public String getVersion()
 {
  return version;
 }

 public void setVersion(String version)
 {
  this.version = version;
 }

 public List<CreateDb> getCreateDbs()
 {
  return createDbs;
 }

 public void setCreateDbs(List<CreateDb> createDbs)
 {
  this.createDbs = createDbs;
 }

}



CreateDb.class

/**
 * @ClassName: CreateDb
 * @Description: 創(chuàng)建數(shù)據(jù)庫腳本
 *
 */
public class CreateDb
{
 /**
  * 數(shù)據(jù)庫表名
  */
 private String name;

 /**
  * 創(chuàng)建表的sql語句集合
  */
 private List<String> sqlCreates;

 public CreateDb(Element ele)
 {
  name = ele.getAttribute("name");

  {
   sqlCreates = new ArrayList<String>();
   NodeList sqls = ele.getElementsByTagName("sql_createTable");
   for (int i = 0; i < sqls.getLength(); i++)
   {
    String sqlCreate = sqls.item(i).getTextContent();
    this.sqlCreates.add(sqlCreate);
   }
  }
 }

 public String getName()
 {
  return name;
 }

 public void setName(String name)
 {
  this.name = name;
 }

 public List<String> getSqlCreates()
 {
  return sqlCreates;
 }

 public void setSqlCreates(List<String> sqlCreates)
 {
  this.sqlCreates = sqlCreates;
 }

}



4、萬事俱備只欠東風(fēng): UpdateManager.class

public class UpdateManager {
    private File parentFile = ContUtils.parentFile;
    private File bakFile = ContUtils.bakFile;
    private List<User> userList;

    public void startUpdateDb(Context context) {
        //讀取XML文件,將XML內(nèi)容轉(zhuǎn)化為對應(yīng)對象
        UpdateDbXml updateDbxml = DomUtils.readDbXml(context);
        //    下載 上一個(gè)版本  --》下一個(gè)版本  【注:在下載時(shí),需要將舊版本、新版本以逗號(hào)的形式寫入文件緩存】
        String[] versions = FileUtil.getLocalVersionInfo(new File(parentFile,
                "update.txt"));
        String lastVersion = versions[0];//拿到上一個(gè)版本
        String thisVersion = versions[1];//拿到當(dāng)前版本

        //數(shù)據(jù)庫File原地址
        String userFile = ContUtils.sqliteDatabasePath;
        //數(shù)據(jù)庫File備份地址
        String user_bak = ContUtils.copySqliteDatabasePath;
        //升級前,數(shù)據(jù)庫File備份
        FileUtil.CopySingleFile(userFile, user_bak);
        //根據(jù)對應(yīng)新舊版本號(hào)查詢XML轉(zhuǎn)化對象里面的腳本,得到對應(yīng)升級腳本
        UpdateStep updateStep = DomUtils.findStepByVersion(updateDbxml, lastVersion, thisVersion);
        if (updateStep == null) {
            return;
        }
        //拿到對應(yīng)升級腳本
        List<UpdateDb> updateDbs = updateStep.getUpdateDbs();
        try {
            //將原始數(shù)據(jù)庫中所有的表名 更改成 bak_表名(數(shù)據(jù)還在)
            executeBeforesSql(updateDbs);
            //檢查新表,創(chuàng)建新表
            CreateVersion createVersion = DomUtils.findCreateByVersion(updateDbxml, thisVersion);
            executeCreateVersion(createVersion);
            //將原來bak_表名  的數(shù)據(jù)遷移到 新表中
            executeAftersSql(updateDbs);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void executeAftersSql(List<UpdateDb> updateDbs) throws Exception {
        for (UpdateDb db : updateDbs) {
            if (db == null || db.getName() == null) {
                throw new Exception("db or dbName is null;");
            }
            List<String> sqls = db.getSqlAfters();
            SQLiteDatabase sqlitedb = getDb();
            //執(zhí)行數(shù)據(jù)庫語句
            executeSql(sqlitedb, sqls);
            sqlitedb.close();
        }
    }


    private void executeCreateVersion(CreateVersion createVersion) throws Exception {
        if (createVersion == null || createVersion.getCreateDbs() == null) {
            throw new Exception("createVersion or createDbs is null;");
        }
        for (CreateDb cd : createVersion.getCreateDbs()) {
            if (cd == null || cd.getName() == null) {
                throw new Exception("db or dbName is null when createVersion;");
            }
            // 創(chuàng)建數(shù)據(jù)庫表sql
            List<String> sqls = cd.getSqlCreates();
            SQLiteDatabase sqlitedb = getDb();
            executeSql(sqlitedb, sqls);
            sqlitedb.close();

        }
    }


    //所有的表名 更改成 bak_表名(數(shù)據(jù)還在)
    private void executeBeforesSql(List<UpdateDb> updateDbs) throws Exception {
        for (UpdateDb db : updateDbs) {
            if (db == null || db.getName() == null) {
                throw new Exception("db or dbName is null;");
            }
            List<String> sqls = db.getSqlBefores();
            SQLiteDatabase sqlitedb = getDb();
            //執(zhí)行數(shù)據(jù)庫語句
            executeSql(sqlitedb, sqls);
            sqlitedb.close();

        }
    }

    private SQLiteDatabase getDb() {
        String dbfilepath = null;
        SQLiteDatabase sqlitedb = null;

        dbfilepath = ContUtils.sqliteDatabasePath;// logic對應(yīng)的數(shù)據(jù)庫路徑
        if (dbfilepath != null) {
            File f = new File(dbfilepath);
            f.mkdirs();
            if (f.isDirectory()) {
                f.delete();
            }
            sqlitedb = SQLiteDatabase.openOrCreateDatabase(dbfilepath, null);
        }
        return sqlitedb;
    }


    private void executeSql(SQLiteDatabase sqlitedb, List<String> sqls) {
        // 檢查參數(shù)
        if (sqls == null || sqls.size() == 0) {
            return;
        }
        sqlitedb.beginTransaction();
        for (String sql : sqls) {
            sql = sql.replaceAll("\r\n", " ");
            sql = sql.replaceAll("\n", " ");
            if (!"".equals(sql.trim())) {
                try {
                    // Logger.i(TAG, "執(zhí)行sql:" + sql, false);
                    sqlitedb.execSQL(sql);
                } catch (SQLException e) {
                }
            }
        }

        sqlitedb.setTransactionSuccessful();
        sqlitedb.endTransaction();
    }

}

到此這篇關(guān)于Android 架構(gòu)之?dāng)?shù)據(jù)庫框架升級的文章就介紹到這了,更多相關(guān)Android 架構(gòu)之?dāng)?shù)據(jù)庫框架內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android基于opencv實(shí)現(xiàn)多通道分離與合并

    Android基于opencv實(shí)現(xiàn)多通道分離與合并

    針對圖像多通道的分離與混合,OpenCV 4中提供了split()函數(shù)和merge()函數(shù)用于解決這些需求。本文講解一下Android如何調(diào)用這些函數(shù)實(shí)現(xiàn)多通道分離與合并
    2021-06-06
  • Android App 與 U 盤通信示例詳解

    Android App 與 U 盤通信示例詳解

    本篇文章主要介紹了Android App 與 U 盤通信詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-01-01
  • Android仿微信通訊錄滑動(dòng)快速定位功能

    Android仿微信通訊錄滑動(dòng)快速定位功能

    這篇文章主要介紹了Android仿微信通訊錄滑動(dòng)快速定位功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-03-03
  • Android 四種獲取屏幕寬度的方法總結(jié)

    Android 四種獲取屏幕寬度的方法總結(jié)

    這篇文章主要介紹了Android 四種獲取屏幕寬度的方法總結(jié)的相關(guān)資料,這里對四種方法進(jìn)行了一一介紹,需要的朋友可以參考下
    2017-01-01
  • Android自定義拋出異常的方法詳解

    Android自定義拋出異常的方法詳解

    這篇文章主要給大家介紹了關(guān)于Android自定義拋出異常的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Retrofit2日志攔截器的使用

    Retrofit2日志攔截器的使用

    這篇文章主要介紹了Retrofit2日志攔截器的使用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-11-11
  • Android 退出應(yīng)用程序的實(shí)現(xiàn)方法

    Android 退出應(yīng)用程序的實(shí)現(xiàn)方法

    這篇文章主要介紹了Android 退出應(yīng)用程序的實(shí)現(xiàn)方法的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • 解決Error:All flavors must now belong to a named flavor dimension. Learn more at https://d.android.com

    解決Error:All flavors must now belong to a named flavor dimens

    這篇文章主要介紹了解決Error:All flavors must now belong to a named flavor dimension. Learn more at https://d.android.com,需要的朋友可以參考下
    2017-11-11
  • Android 開啟閃光燈做手電筒的詳解

    Android 開啟閃光燈做手電筒的詳解

    本篇文章是對Android中開啟閃光燈做手電筒的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • Android中shape定義控件的使用

    Android中shape定義控件的使用

    Android中常常使用shape來定義控件的一些顯示屬性,接下來通過本篇文章給大家介紹Android中shape定義控件的使用,對android shape定義控件相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧
    2016-01-01

最新評論