您的位置:首页 > 编程语言 > Java开发

Java mkdir() 导致的Bug

2016-08-23 13:39 344 查看
原文地址:https://www.zybuluo.com/linux1s1s/note/132124

而且有一点我比较好奇的是,为什么有些机型有这个问题(红米,Android5.1.1),而有些机型不会有这个问题呢(红米,Android4.4.2)?

以下是正文:

有些Bug你可能怎么想也想不通,请始终铭记出现Bug首先看看自己的代码哪里出问题了,而不是一直在那郁闷吐槽。废话说到这里,下面直接上干货:

//得到SD卡路径

private final static String DATABASE_PATH = android.os.Environment.getExternalStorageDirectory().getAbsolutePath()

+ "/com/cn21/account/public";

//数据库名

private final static String DATABASE_FILENAME = "account.db3";


public class AccountDBHelper{

private static SQLiteDatabase initDatabase(){

String databaseFilename = DATABASE_PATH + "/" + DATABASE_FILENAME;

File dir = new File(DATABASE_PATH);

if(!dir.exists())

dir.mkdir();

SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(databaseFilename, null);

db.execSQL(sql_user);

return db;

}

}


上面代码有啥问题? 

如果一旦使用上面代码片段,很可能会抛出以下异常:

01-02 13:29:17.601: E/SQLiteDatabase(2258): Failed to open database '/storage/emulated/0/com/cn21/account/public/account.db3'.

01-02 13:29:17.601: E/SQLiteDatabase(2258): android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:339)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:236)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:515)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:207)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:178)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:891)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:859)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:696)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:1249)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:1238)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:236)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at com.cn21.account.lib.db.AccountDBHelper.initDatabase(AccountDBHelper.java:114)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at com.cn21.account.lib.db.AccountDBHelper.getCache(AccountDBHelper.java:73)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at com.cn21.account.lib.ui.LoginActivity.onCreate(LoginActivity.java:71)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at android.app.Activity.performCreate(Activity.java:5372)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1104)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2270)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2362)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at android.app.ActivityThread.access$700(ActivityThread.java:168)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1329)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at android.os.Handler.dispatchMessage(Handler.java:99)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at android.os.Looper.loop(Looper.java:137)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at android.app.ActivityThread.main(ActivityThread.java:5493)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at java.lang.reflect.Method.invokeNative(Native Method)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at java.lang.reflect.Method.invoke(Method.java:525)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)

01-02 13:29:17.601: E/SQLiteDatabase(2258):     at dalvik.system.NativeStart.main(Native Method)


上面异常大概是说不能打开数据库,所以抛出异常

那么为什么会打不开呢? 按照正常的思维是先检验文件是否存在,如果存在,则直接使用,如果不存在,那么创建相应的目录,所以左思右想,上面的Crash不该有啊。

其实上面的代码有明显的问题,这里先提示一下:

dir.mkdir()

dir.mkdirs()


上面两个方法有啥区别?mkdir()不会创建所有层级,而mkdirs()则可以。对的,就是这个方法的误用导致上面的问题。如果不清楚为啥,可以自行查阅Java JDK,这里不再赘述。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: