项目中引入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]]
既然是没有初始化,找到问题所在就进行初始化操作:
@Override
protected void attachBaseContext(Context context) {
super.attachBaseContext(context);
MultiDex.install(context);
}
apply plugin: 'org.greenrobot.greendao' // apply plugin
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
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
}
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
}
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();
}
@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方法
}
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