greendao的使用及碰到的错误greendaDid not find class androidx core content FileProvider on path DexPathList

项目中引入greendao之后,出现下面的问题,其原因是因为用了MtltiDex分包,但是没有初始化的原因

异常信息:

ClassNotFoundException: Didn't find class "XXXX" on path: DexPathList[[zip file "/data/app/[包名]-1.apk"],nativeLibraryDirectories=[/data/app-lib/[包名]-1, /vendor/lib, /system/lib]]

既然是没有初始化,找到问题所在就进行初始化操作:

在自己的application类中重写attachBaseContext方法,添加初始化代码即可,纯是因为自己蠢才犯的错,人家greendao不背这个错的锅

 @Override
    protected void attachBaseContext(Context context) {
        super.attachBaseContext(context);
        MultiDex.install(context);
    }

greendao的引入

app.gradle

一、添加greendao插件

apply plugin: 'org.greenrobot.greendao' // apply plugin

 第二步:添加编译选项,一般在引用的过程中是要出问题的 所以加上这个没错

compileOptions {
        sourceCompatibility = 1.8
        targetCompatibility = 1.8
    }

 第三步:配置greenDao的数据库版本号以及自动生成的包名的路径及其他

greendao{
    schemaVersion 1 // 数据库版本号 除了此段必须,其他均非必须
    daoPackage  //greenDao 自动生成的代码保存的包名
    targetGenDir   'src/main/java' //自动生成的代码存储的路径,默认是             
    build/generated/source/greendao.
    generateTests false //true的时候自动生成测试单元
    targetGenDirTests: 测试单元的生成目录默认是 src/androidTest/java
}

第四步:引入依赖

dependencies {
    implementation 'androidx.multidex:multidex:2.0.0'
    implementation 'org.greenrobot:greendao:3.2.2' // add library
    implementation 'org.greenrobot:greendao-generator:3.2.2' // add library
}

项目工程下的build.gradle

buildscript {
    repositories {
        google()
        jcenter()
        mavenCentral() // add repository
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.2'
        classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2'
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        maven { url "https://jitpack.io" }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

到此完成greendao的依赖

那么接下来就是greendao的使用

一、在application中实例化greendao

 public static DaoSession daoSession;

    public static DaoSession getDaoSession() {
        return daoSession;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        initGreenDao();
    }

    /**
     * 初始化GreenDao 
     */
    private void initGreenDao() {
        DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "hanhan.db");
        SQLiteDatabase db = helper.getWritableDatabase();
        DaoMaster daoMaster = new DaoMaster(db);
        daoSession = daoMaster.newSession();
    }

二、创建一个bean的实体类,用于进行数据库表的创建

@Entity
public class TransBean {
    @Id(autoincrement = true) // 主键自增
    Long id;
    @Property(nameInDb = "user") // 在数据表中的字段名称
    String user;
    @Property(nameInDb = "date")
    String date;
    @Property(nameInDb = "hotel")
    String hotel;
    @Property(nameInDb = "car")
    String car;
    @Property(nameInDb = "carCode")
    String carCode;
// 省略了get set方法
    }

 添加完成之后,选择工具栏Build-Make Project 等待编译完成,完成之后 在build编译文件和实体列里面会有下图所示结构 均为自动生成,这时数据库表算是创建完了 需要注意的是如果要重新添加表字段 要重新生成构造,并将apk文件卸载,不然更新的数据库表是无法创建的。

greendao的使用及碰到的错误greendaDid not find class androidx core content FileProvider on path DexPathList_第1张图片

 三、完成上述创建之后我们可以新建一个DbUtil工具类来实现数据库信息的增、删、改、查操作了

public class TransDbUtil {
    Context mContext;
    private final TransBeanDao dao;
    private DaoSession mDaoSession;

    public TransDbUtil(Context context) {
        mContext = context;
        mDaoSession = MyApplication.getDaoSession();
        dao = mDaoSession.getTransBeanDao();
    }

    /**
     * 查询所有的订单信息
     *
     * @return
     */
    public List loadAll() {
        mDaoSession.clear();
        List list = dao.loadAll();
        return list;
    }

    /**
     * 条件查询
     */
    public List quryByLimit(String hotel) {
        QueryBuilder builder = dao.queryBuilder();
        List list = builder.where(TransBeanDao.Properties.Hotel.eq(hotel)).list();
        return list;

    }

    /**
     * 插入一条数据
     *
     * @param bean
     * @return
     */
    public boolean insertData(TransBean bean) {
        boolean insert = dao.insert(bean) == -1 ? false : true;
        return insert;
    }

    /**
     * 删除一条数据
     *
     * @param key
     */
    public boolean deleteData(long key) {
        boolean isCom;
        try {
            dao.deleteByKey(key);

            isCom = true;
        } catch (Exception e) {
            e.printStackTrace();
            isCom = false;
        }
        return isCom;
    }

    /**
     * 更新一条数据
     * @param bean
     * @return
     */
    public boolean updateData(TransBean bean) {
        boolean isCom;
        try {
            dao.update(bean);
            isCom = true;
        } catch (Exception e) {
            e.printStackTrace();
            isCom = false;
        }
        return isCom;
    }

    /**
     * 关闭
     */
    public void closeDaoSession() {
        if (mDaoSession != null) {
            mDaoSession.clear();
            mDaoSession = null;
        }
    }


}

 上述代码是一个简单的操作示意,具体要根据自己的需要进行具体的代码实现

 

上面提到了MultiDex,那么这里多嘴解释一下MultiDex分包:

Android 5.0 之前版本的 Dalvik 可执行文件分包支持

Android 5.0(API 级别 21)之前的平台版本使用 Dalvik 运行时来执行应用代码。默认情况下,Dalvik 限制应用的每个 APK 只能使用单个 classes.dex 字节码文件。要想绕过这一限制,您可以使用 MultiDex,它会成为您的应用主要 DEX 文件的一部分,然后管理对其他 DEX 文件及其所包含代码的访问。

当Android系统安装一个应用的时候,有一步是对Dex进行优化,这个过程有一个专门的工具来处理,叫DexOpt。DexOpt的执行过程是在第一次加载Dex文件的时候执行的。这个过程会生成一个ODEX文件,即Optimised Dex。执行ODex的效率会比直接执行Dex文件的效率要高很多。

但是在早期的Android系统中,DexOpt有一个问题,DexOpt会把每一个类的方法id检索起来,存在一个链表结构里面。但是这个链表的长度是用一个short类型来保存的,导致了方法id的数目不能够超过65536个。当一个项目足够大的时候,显然这个方法数的上限是不够的。尽管在新版本的Android系统中,DexOpt修复了这个问题,但是我们仍然需要对低版本的Android系统做兼容。

为了解决方法数超限的问题,需要将该dex文件拆成两个或多个,为此谷歌官方推出了multidex兼容包,配合AndroidStudio实现了一个APK包含多个dex的功能。

 

参考博文:

https://blog.csdn.net/wy391920778/article/details/78553379?locationNum=6&fps=1

https://www.cnblogs.com/CharlesGrant/p/5112597.html

 

 

 

 

 

你可能感兴趣的:(Android)