博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
DbUtils应用在Android6.0中为什么会崩溃
阅读量:7050 次
发布时间:2019-06-28

本文共 2846 字,大约阅读时间需要 9 分钟。

序言

最近研究了一个手机开门的功能,在Android4.X/5.X测试都通过了,后来在Android6.0上测试崩溃了,适配出现了问题,到底是什么原因呢?

分析

Logcat里面的报错信息是这样的

java.lang.NullPointerException: Attempt to invoke virtual method 'int android.database.sqlite.SQLiteDatabase.getVersion()' on a null object reference
初始化数据库出现了问题,获取不到数据库的版本号,刚开始以为是开门的jar包不兼容,导致创建数据库失败,但是经过查找资料和反复调试,发现问题出在DbUtils上,到底是什么问题呢?

首先了解一下DbUtils的框架结构,总体来看分为7个部分:

1、create instance(创建实例)
2、operations(操作部分)
3、config(配置)
4、private operations with out transaction(无业务的操作)
5、tools(工具)
6、exec sql(sql执行)
7、temp cache(临时缓存)

其中在创建数据库的时候提供了5种构造方法

(1)通过传入上下文创建DB,这种情况下使用的是系统默认的配置

dbName = xUtils.db, dbVersion = 1;      public static DbUtils create(Context context) {        DaoConfig config = new DaoConfig(context);        return getInstance(config);    }

(2)通过传入上下文和dbName,根据用户指定的dbName生成数据库

public static DbUtils create(Context context, String dbName) {    DaoConfig config = new DaoConfig(context);    config.setDbName(dbName);    return getInstance(config);}

(3) 通过传入上下文 、dbDir、dbName,根据用户指定的dbName在dbDir位置生成数据库

public static DbUtils create(Context context, String dbDir, String dbName) {

DaoConfig config = new DaoConfig(context);    config.setDbDir(dbDir);    config.setDbName(dbName);    return getInstance(config);}

(4) 通过传入上下文 、dbName,dbVersion、dbUpgradeListener根据用户指定的dbName生成dbVersion版 的数据库

public static DbUtils create(Context context, String dbName, int dbVersion, DbUpgradeListener dbUpgradeListener) {

DaoConfig config = new DaoConfig(context);    config.setDbName(dbName);    config.setDbVersion(dbVersion);    config.setDbUpgradeListener(dbUpgradeListener);    return getInstance(config);}

(5) 通过传入上下文 、dbName,dbVersion、dbUpgradeListener,根据用户指定的dbName生成dbVersion的数据库 ,指定监听器

public static DbUtils create(Context context, String dbDir, String dbName, int dbVersion, DbUpgradeListener dbUpgradeListener) {

DaoConfig config = new DaoConfig(context);    config.setDbDir(dbDir);    config.setDbName(dbName);    config.setDbVersion(dbVersion);    config.setDbUpgradeListener(dbUpgradeListener);    return getInstance(config);}

5种方法怎么选择呢?我们看下用于配置数据库的5个属性

private Context context; //上下文private String dbDir;//数据库存储路径private String dbName = “xUtils.db”; // 数据库名称 private int dbVersion = 1; //版本号private DbUpgradeListener dbUpgradeListener;//监听器

为了方便我们后期查找,一般会选择第三种构造方法,指定上下文,指定数据库的名称,指定数据库存储路径,大多数情况这是没有问题的,但是Android6.0和以前的版本相比,对存储路径做了修改,所以根据Android4.X/5.X给出的指定存储路径不适用于6.0版本,创建数据库失败,就出现的文章开头的错误,获取数据库版本号失败。

找到了问题所在,那么解决起来就相对简单了,只要选择第一种构造方法,指定上下文,其他属性根据系统自动适配就可以了。

其实还有一种相对简单的解决方法,作为手机端,大部分数据都是从服务器获取的,在数据量不是很大的情况下,并不需要去生成数据库,可以在获取数据后,只做一个简单的缓存,保存到集合中,如List,map等,大多数页面现在都是这样实现的。

其实出现这种情况的不光是Android6.0,由于市场上Android手机品牌型号较多,不同品牌,不同型号的手机,为了实现某些个性化功能,或者出于优化内存等方面的考虑,经常会篡改手机的存储路径,之前在做其他功能,比如获取手机本地的视频文件,图片文件等,都遇到了这样的适配问题,下次有时间再分享。

总结

遇到不熟悉的错误信息,可以把错误信息复制出来,通过百度大体了解一下,出现这种错误都有些什么原因,把握好大方向,然后从熟悉的内容入手,分析可能出现错误代码的内部机制,找出可能会产生相关错误的点,逐步排除改进,最后解决问题。

转载地址:http://lccol.baihongyu.com/

你可能感兴趣的文章
工控随笔_07_西门子_WinCC利用命令行实现操作log日志
查看>>
解决MySQL报错The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents ........
查看>>
HUST 1017 Exact cover
查看>>
SessionStateStoreProviderBase.GetItemExclusive Method
查看>>
Excel Wrapper
查看>>
Thread和Service应用场合的区别
查看>>
poj 2632 模拟题
查看>>
递归--木棍问题
查看>>
企业门户(Portal)项目实施方略与开发指南
查看>>
基于百度定位SDK的定位服务的实现
查看>>
是你的,就是你的。越是紧握,越容易失去。
查看>>
[LeetCode] Implement Stack using Queues
查看>>
cherrypy安装使用,配置python环境变量
查看>>
MVC验证12-使用DataAnnotationsExtensions对整型、邮件、最小值、文件类型、Url地址等验证...
查看>>
Source not found
查看>>
【CLRS】《算法导论》读书笔记(一):堆排序(Heapsort)
查看>>
支持类型过滤的枚举器
查看>>
HDU 4275 Color the Tree(树同构)
查看>>
php里Array2xml
查看>>
以boost::function和boost:bind取代虚函数
查看>>