Java mkdir() 导致的Bug

原文地址:https://www.zybuluo.com/linux1s1s/note/132124


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


以下是正文:


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

  
  
  
  
  1. //得到SD卡路径
  2. private final static String DATABASE_PATH = android.os.Environment.getExternalStorageDirectory().getAbsolutePath()
  3. + "/com/cn21/account/public";
  4. //数据库名
  5. private final static String DATABASE_FILENAME = "account.db3";
  6. public class AccountDBHelper{
  7. private static SQLiteDatabase initDatabase(){
  8. String databaseFilename = DATABASE_PATH + "/" + DATABASE_FILENAME;
  9. File dir = new File(DATABASE_PATH);
  10. if(!dir.exists())
  11. dir.mkdir();
  12. SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(databaseFilename, null);
  13. db.execSQL(sql_user);
  14. return db;
  15. }
  16. }

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

  
  
  
  
  1. 01-02 13:29:17.601: E/SQLiteDatabase(2258): Failed to open database '/storage/emulated/0/com/cn21/account/public/account.db3'.
  2. 01-02 13:29:17.601: E/SQLiteDatabase(2258): android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
  3. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
  4. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:339)
  5. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:236)
  6. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:515)
  7. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:207)
  8. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:178)
  9. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:891)
  10. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:859)
  11. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:696)
  12. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:1249)
  13. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:1238)
  14. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:236)
  15. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at com.cn21.account.lib.db.AccountDBHelper.initDatabase(AccountDBHelper.java:114)
  16. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at com.cn21.account.lib.db.AccountDBHelper.getCache(AccountDBHelper.java:73)
  17. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at com.cn21.account.lib.ui.LoginActivity.onCreate(LoginActivity.java:71)
  18. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at android.app.Activity.performCreate(Activity.java:5372)
  19. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1104)
  20. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2270)
  21. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2362)
  22. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at android.app.ActivityThread.access$700(ActivityThread.java:168)
  23. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1329)
  24. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at android.os.Handler.dispatchMessage(Handler.java:99)
  25. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at android.os.Looper.loop(Looper.java:137)
  26. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at android.app.ActivityThread.main(ActivityThread.java:5493)
  27. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at java.lang.reflect.Method.invokeNative(Native Method)
  28. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at java.lang.reflect.Method.invoke(Method.java:525)
  29. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
  30. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
  31. 01-02 13:29:17.601: E/SQLiteDatabase(2258): at dalvik.system.NativeStart.main(Native Method)

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

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

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

  
  
  
  
  1. dir.mkdir()
  2. dir.mkdirs()

上面两个方法有啥区别?mkdir()不会创建所有层级,而mkdirs()则可以。对的,就是这个方法的误用导致上面的问题。如果不清楚为啥,可以自行查阅Java JDK,这里不再赘述。

你可能感兴趣的:(Java mkdir() 导致的Bug)