Android 架构之数据库框架升级

目录
  • 1、备份原数据库File文件
  • 2、数据库升级XML编写 updateXml.xml
  • 3、创建XML解析器
    • 3.1 对应工具类 DomUtils.class
    • 3.2 对应XML的实体类
  • 4、万事俱备只欠东风: UpdateManager.class

前言:

上一篇讲解了Android 架构之数据框架搭建 ,里面含有数据库最基础的增删改查功能,不过只考虑了单数据库,开发者可以举一反三按照对应思路设计多数据库架构。 在本篇里,将会讲解令开发者比较头疼的数据库升级。

话不多说,先来看代码效果,看看是否是想要的

如上图所示:

  • 当前APP版本号为V007;
  • V001、V002升级到V007有对应的处理逻辑;
  • V003、V004、V005、V006升级到V007也有对应的处理逻辑;
  • 同理可实现任意版本可阔多个版本升级到最新数据库;

开始之前我们先理一下数据库升级的逻辑

  1. 任何数据库在操作之前,我们最好有一个数据库备份,所以这里得要备份对应的数据库File文件;
  2. 任何数据表在操作之前,也要有一个数据表备份,所以这里会在原表名加前后缀操作;
  3. 在数据表升级的时候,有些时候可能会对表名、表列做任意增删改的操作,所以这里每次都要创建一个全新的表;
  4. 全新表创建好了,但是一张空表,这里就需要查询对应加了前后缀的原表数据,将对应数据添加至新表里;
  5. 数据全部拷贝完成时,为了让用户有良好的体验,我们需要删除对应加了前后缀的原表;
  6. 对应原表删除完毕时,我们需要删除对应备份数据库的File文件。

总结:

  • 操作【1】和【6】 这俩操作 属于 java代码执行
  • 其他【2】、【3】、【4】、【5】 这些操作,都属于SQL操作
  • 但SQL操作,通过效果图发现,是写在XML文件里面的,所以需要写一个XML解析器

现在我们就按照对应步骤一一讲解

1、备份原数据库File文件

    /**
     * 复制单个文件(可更名复制)
     *
     * @param oldPathFile 准备复制的文件源
     * @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()) { //文件存在时
                InputStream inStream = new FileInputStream(oldPathFile); //读入原文件
                FileOutputStream fs = new FileOutputStream(newPathFile);
                byte[] buffer = new byte[1024];
                while ((byteread = inStream.read(buffer)) != -1) {
//                    bytesum += byteread; //字节数 文件大小
                    fs.write(buffer, 0, byteread);
                }
                inStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

总结:这也没啥可说的,就一个很简单的文件复制。

2、数据库升级XML编写 updateXml.xml

<?xml version="1.0" encoding="utf-8"?>
<updateXml>
    <createVersion version="V007">
        <createDb name="hqk">  <!-- 要升级数据库对应名 ,如果应用含多个数据库,那么可以创建多个 createDb 标签-->
            <sql_createTable>  <!-- 创建最新的表结构 -->
                <!--
                     @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对应版本的app升级到 最新V007版本的升级逻辑-->
    <updateStep versionFrom="V001,V002" versionTo="V007">
        <!-- 对应数据升级逻辑,对应上面的 createDb 标签name ,如果有多对 createDb,这里也可执行多对 updateDb-->
        <updateDb name="hqk">
            <sql_before> <!-- 将V001,V002对应的旧表重命名备份-->
                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>

    <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>

总结:

  • createVersion 标签 ,表示 当前 最新APP版本需要操作的内容
  • createDb 标签,表示当前最新对应的数据库要操作的内容,可多组标签,实现多个数据库升级
  • sql_createTable 标签,表示当前最新对应的数据表要操作的内容,可多组标签,实现多表升级
  • updateStep 标签,表示不同版本要升级的对象,可多组标签,达到不同版本数据库升级到最新数据库的效果
  • updateDb 标签,表示旧版本要修改的对应数据库
  • sql_before 标签,表示数据库升级时优先级最高的SQL,(在新表创建前执行)
  • sql_after 标签,表示数据库升级时优先级最低并按顺序执行的SQL(在新表创建后执行)

3、创建XML解析器

3.1 对应工具类 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;
    }
    /**
     * 新表插入数据
     *
     * @param xml
     * @param lastVersion 上个版本
     * @param thisVersion 当前版本
     * @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 {
                // 升级来源以逗号分隔
                String[] lastVersionArray = step.getVersionFrom().split(",");
                if (lastVersionArray != null && lastVersionArray.length > 0) {
                    for (int i = 0; i < lastVersionArray.length; i++) {
                        // 有一个配到update节点即升级数据
                        if (lastVersion.equalsIgnoreCase(lastVersionArray[i]) && step.getVersionTo().equalsIgnoreCase(thisVersion)) {
                            thisStep = step;
                            break;
                        }
                    }
                }
            }
        }
        return thisStep;
    }

    /**
     * 解析出对应版本的建表脚本
     *
     * @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中逗号分隔
                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 对应XML的实体类

UpdateDbXml

/**
 * @ClassName: UpdateDbXml
 * @Description: 升级更新数据库
 *
 */
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 各个升级的版本:"+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","各个升级的版本:"+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: 数据库升级脚本信息
 */
public class UpdateStep
{
 /**
  * 旧版本
  */
 private String versionFrom;

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

 /**
  * 更新数据库脚本
  */
 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: 更新数据库脚本
 *
 */
public class UpdateDb
{
 /**
  * 数据库名称
  */
 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;

 /**
  * 创建数据库表脚本
  */
 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: 创建数据库脚本
 *
 */
public class CreateDb
{
 /**
  * 数据库表名
  */
 private String name;

 /**
  * 创建表的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、万事俱备只欠东风: 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内容转化为对应对象
        UpdateDbXml updateDbxml = DomUtils.readDbXml(context);
        //    下载 上一个版本  --》下一个版本  【注:在下载时,需要将旧版本、新版本以逗号的形式写入文件缓存】
        String[] versions = FileUtil.getLocalVersionInfo(new File(parentFile,
                "update.txt"));
        String lastVersion = versions[0];//拿到上一个版本
        String thisVersion = versions[1];//拿到当前版本

        //数据库File原地址
        String userFile = ContUtils.sqliteDatabasePath;
        //数据库File备份地址
        String user_bak = ContUtils.copySqliteDatabasePath;
        //升级前,数据库File备份
        FileUtil.CopySingleFile(userFile, user_bak);
        //根据对应新旧版本号查询XML转化对象里面的脚本,得到对应升级脚本
        UpdateStep updateStep = DomUtils.findStepByVersion(updateDbxml, lastVersion, thisVersion);
        if (updateStep == null) {
            return;
        }
        //拿到对应升级脚本
        List<UpdateDb> updateDbs = updateStep.getUpdateDbs();
        try {
            //将原始数据库中所有的表名 更改成 bak_表名(数据还在)
            executeBeforesSql(updateDbs);
            //检查新表,创建新表
            CreateVersion createVersion = DomUtils.findCreateByVersion(updateDbxml, thisVersion);
            executeCreateVersion(createVersion);
            //将原来bak_表名  的数据迁移到 新表中
            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();
            //执行数据库语句
            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;");
            }
            // 创建数据库表sql
            List<String> sqls = cd.getSqlCreates();
            SQLiteDatabase sqlitedb = getDb();
            executeSql(sqlitedb, sqls);
            sqlitedb.close();

        }
    }

    //所有的表名 更改成 bak_表名(数据还在)
    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();
            //执行数据库语句
            executeSql(sqlitedb, sqls);
            sqlitedb.close();

        }
    }

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

        dbfilepath = ContUtils.sqliteDatabasePath;// logic对应的数据库路径
        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) {
        // 检查参数
        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, "执行sql:" + sql, false);
                    sqlitedb.execSQL(sql);
                } catch (SQLException e) {
                }
            }
        }

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

}

到此这篇关于Android 架构之数据库框架升级的文章就介绍到这了,更多相关Android 架构之数据库框架内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android操作系统的架构设计分析

    之前一直在Android应用层上做工作,最近开始研究Android平台上的东东了,主要是在Android Frameworks层和系统库层进行研究.以下是我自己的理解,领悟,希望与大家一块分享. Android系统架构分为Linux内核驱动.C/C ++框架.Java框架.Java应用程序. Android应用层: Android应用程序需要Java框架支持.主要是针对手机用户的.Android应用层都是由Java代码写的,运行在虚拟机中.虚拟机在Android平台中扮演着很重要的角色.虚拟机在

  • 浅析Android系统的架构以及程序项目的目录结构

    Android框架结构 直接上图: 由上图,我们可以看出Android系统架构由5部分组成, 分别是:Linux Kernel(linux内核).Android Runtime(运行时环境).Libraries(类库).Application Framework(应用框架).Applications(应用). 1.1.Linux Kernel Android基于Linux 2.6提供核心系统服务,例如:安全.内存管理.进程管理.网络堆栈.驱动模型.Linux Kernel也作为硬件和软件之间的抽

  • Android Jetpack架构组件 ViewModel详解

    前言 前面两篇文章我们已经学习了Lifecycle和DataBind,本篇文章我们来学习Jetpack系列中比较重要的ViewModel,Jetpack的很多很多组件都是搭配使用的,所以单独的知识点可能会有些"无意义"但却是我们项目实战的基础! ViewModel的使用 ViewModel类旨在以注重生命周期的方式存储和管理界面相关的数据.ViewModel类让数据可在发生屏幕旋转等配置更改后继续存在.这句话很好理解,还记得我们在讲解Lifecycle的时候 举的例子吗,我们还是使用那

  • Android App的运行环境及Android系统架构概览

    Android基于linux内核,面向移动终端的操作系统.主要包括以下几个方面: Application Framework: 这一层为应用开发者提供了丰富的应用编程接口,如 Activity Manager,Content Provider,Notification Manager,以及各种窗口 Widget 资源等.所有的APP都是运行在这一层之上. Dalvik 虚拟机: Dalvik VM采用寄存器架构,而不是JVM的栈架构,更适于移动设备.java源代码经过编译成为.class字节码文

  • Android应用架构思想分析

    算算日子,工作刚好三年了.这篇开始,鄙人就要向着各种以前想起来就头大的方向努力前进了.作为在Android应用层搬砖多年的民工,首篇我想谈谈自己对架构思想的一些看法.如有不妥,还请拍砖. 盖楼的故事(虚构) 有一块地,两个区域,开发商分别让两个包工头负责开发. 包工头A办事干净利落,甩开膀子就开工了.为了省钱雇了一个全能的工人,他既要去采购盖房的材料,又要用这些材料盖房子.起初底层屋子结构简单,还能应付得来,到了后面复杂的设计需求时,忙的不可开交,经常精疲力尽,阻断了盖房子的进程,使得老板很是不

  • Android 生命周期架构组件使用方法

    Support Library 26.1+ 直接支持生命周期架构组件.使用该组件,Android 生命周期的梦魇已经成为过去.再也不用担心出现 Can not perform this action after onSaveInstanceState 这样的异常了. 笔者封装了一个简化使用该组件的辅助类,大约 70 行代码: public class LifecycleDelegate implements LifecycleObserver { private LinkedList<Runna

  • Android视图控件架构分析之View、ViewGroup

    在Android中,视图控件大致被分为两类,即ViewGroup和View,ViewGroup控件作为父控件,包含并管理着子View,通过ViewGroup和View便形成了控件树,各个ViewGoup对象和View对象就是控件树中的节点.在控件树中,以树的深度来遍历查找对应的控件元素,同时,上层控件负责子控件的测量与绘制,并传递交互事件. Android控件树: AndroidUI界面架构图: 一.测量View的工具类:MeasureSpec 1.MeasureSpec包含了测量的模式和测量的

  • Android登录代码MVP架构详解

    登录代码MVP架构的具体实现,分享给大家. MainActivity.java public class MainActivity extends AppCompatActivity implements View.OnClickListener, Mvp.fff { private EditText mUsername; private EditText mPassword; private Button login; private ProgressDialog mProgressDialo

  • Android Jetpack架构组件Lifecycle详解

    前言 Lifecycle是Jetpack架构组件中用来感知生命周期的组件,使用Lifecycles可以帮助我们写出和生命周期相关更简洁更易维护的代码. 生命周期 生命周期这个简单而又重要的知识相信大家早已耳熟能详.假设我们现在有这样一个简单需求: 这个需求只是一个实例,在真实的开发中当然不可能有这样的需要: 在Activity 可见的时候,我们去做一个计数功能,每隔一秒 将计数加1 ,当Activity不可见的时候停止计数,当Activity被销毁的时候 将计数置为0 OK,So easy~ ,

  • Android架构组件Room的使用详解

    Room其实就是一个orm,抽象了SQLite的使用,但是它作为Android的亲儿子orm,并且原生支持LiveData和Rxjava嵌套使用,学习一下还是不错的. Room有3个主要组件 Database :数据库 Entity : 代表数据库一个表结构 Dao : 包含访问数据库的方法 简单使用 添加Google Maven仓库 allprojects { repositories { jcenter() google() } } 添加依赖 dependencies { // Room i

  • 详解Android中的MVP架构分解和实现

    1.概述 传统的Android开发架构一般是MVC模式, Model:业务逻辑和实体模型 View:对应于布局文件 Controllor:对应于Activity 单独从逻辑看起来非常好,与我们做Web开发时,开发模式类似,但在实际开发中,View对应于布局文件,实际上关于该布局文件中的数据绑定的操作,事件处理的代码都在Activity中,Activity既像View又像Controller(MVVP架构中包括数据绑定),导致Activity中职责太重,耦合度大.修改和维护起来非常麻烦. 2.MV

  • Android 架构之数据库框架搭建

    目录 1.先创建对应相关操作的注解 1.1 bTable 标识表 1.2 DbPrimaryKey 标识主键 1.3 DbFiled 标识成员属性 2.创建对应表操作类Dao层 2.1 建 待实现的基层 IBaseDao 2.2 建已实现的基层 BaseDao 2.3 建对应model 的Dao层 3.创建数据库工厂 4.创建对应model 5.最终使用 前言: 你还在苦恼的写SQL么?你还在为数据库升级而烦恼么?你还在因查询数据而写繁琐不可用的代码么? 在这,这些都将不复存在!在本篇中,将会让

随机推荐