请选择 进入手机版 | 继续访问电脑版
Ptlogin
 找回密码
 立即注册

android.database.sqlite.SQLiteFullException:database or disk is full (code 13)

[复制链接]
  • TA的每日心情
    开心
    2016-2-3 18:24
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    107

    主题

    948

    帖子

    3390

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    3390
    发表于 2016-5-17 17:53:20
    出错堆栈
    # [  j: Z9 g& h5 u, f, y" J: j, ~% N
    [Java] 纯文本查看 复制代码
    android.database.sqlite.SQLiteFullException 
    database or disk is full (code 13)
    android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method) 
    android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:782) 
    android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788) 
    android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86) 
    android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1469) 
    xxx.xxx.buglyshare.MainActivity$1.onClick(MainActivity.java:40) 
    android.view.View.performClick(View.java:4448) 
    android.view.View$PerformClick.run(View.java:18461) 
    android.os.Handler.handleCallback(Handler.java:733) 
    android.os.Handler.dispatchMessage(Handler.java:95) 
    android.os.Looper.loop(Looper.java:136) 
    android.app.ActivityThread.main(ActivityThread.java:5072) 
    java.lang.reflect.Method.invokeNative(Native Method) 
    java.lang.reflect.Method.invoke(Method.java:515) 
    com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
    com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609) 
    dalvik.system.NativeStart.main(Native Method)   
    

      ]" t* G* c( r2 _# ^9 m5 Q/ c1 ~/ ]4 ?
    【出错代码】7 d1 Q4 a( R/ `  m$ N1 s
    类:me.bfbrmt.bugly2.MainActivity
    22.png . ^, f0 `% |8 n  k) V
    : _. l: ?  f9 A4 ~
    代码片段(第40行):
    . v5 T# [- g5 s  a: j8 G  b: r- v6 W. |; v2 j* J' d8 o
    【出错原因】' R% Q/ s: b1 Y5 n3 \
    从异常的完整描述:
    “android.database.sqlite.SQLiteFullException: database or disk is full (code 13)”
    很容易看出,这是因为数据库的体积达到最大限制或者磁盘已满。也就是说数据量太大,或者磁盘空间不足。

    9 V; I- `! h; y  o7 w/ a
    分析:
    注意第 24 行的语句“database.setMaximumSize(100000);”。setMaximumSize 方法的功能是设置数据库的最大容量,以字节数计。(需要注意的是,最终数据库的大小可能略大于此值,随后会进行分析。不过这不影响此处的分析,因为不会大太多。)
    接着在第 31 ~ 39 行,向数据库写入大量数据(显然大大超过 100000 字节),从而导致此异常的发生。
    出错猜测:
    1. 数据库数据量超过限制;
    一般地,我们不会去设定数据库的最大容量。在默认情况下,数据库容量是一个很大的值。以我测试用的手机为例,第 24 行获取的是默认容量。第 25 行设定一个最大容量,第 26 行打印当前的最大容量。输出如下:
    图片25.png
    可以看到,默认容量高达约 4 T,这是在手机上几乎不可能达到的限制。而我们设定的值只有 100 K,这是很容易达到的。(此外,读者应该注意到此处的最大容量并不是我们给定的值 100000,而是 102400。这是因为数据库的容量大小必须是页大小的整数倍,如果不足就向上补齐到整数倍,所以最终数值将略大于给定的数值。除此之外,这个值还应该大于当前数据库的容量,也就是说,不能将数据库的最大容量设置为小于当前容量。不过这里我们的应用是第一次运行,所以不会影响。)
    也就是说,如果我们设定了最大容量,就有可能因为这个原因而发生这个错误。反之,若使用默认容量,则几乎不会因为这个原因发生这个错误。
    2. 手机剩余存储空间已满;
    承接上面的分析。如果数据库的最大容量是默认值,或者虽然设定了最大容量,但是最大容量依然大于实际数据量(需要注意的是,实际数据库大小会大于数据库所包含的记录的数据大小,我想这不难理解。),那么就可能是第二个原因导致的,那就是手机剩余存储空间已满。
    注意,一般情况下,使用 openOrCreateDatabase 创建的数据库文件默认放在手机内部存储器中,而不是 SD 卡中。所以这里所谓的“disk is full”是指手机内部存储空间已满,而不是 SD 卡已满。当然在某些情况下,比如应用安装在 SD 卡上时,数据库文件会跟着放在 SD 卡上,那么“disk is full”就是指 SD 卡已满。
    # {# ]6 ]& C" E+ A" s
    【解决方案】
    & Z, g/ @2 M' X6 f9 u1 M) y
    & a" T0 X" I' t! [  ~
    ) B/ G$ h; l. B
    1. 如果是由于限制了数据库最大体积导致的,如果条件允许,可以考虑放松限制。如果这个数据库是别人提供的,那么可以使用 getMaximumSize 获取当前最大容量。
    2. 如果是手机剩余存储空间不足导致的,则可以提醒用户清理垃圾,腾出内部空间。如果是并不敏感的数据,比如并不敏感的缓存数据,可以考虑放到 SD 卡中去。如果数据量非常大,比如视频缓存,更应该考虑放到 SD 卡中去。若是要避免此类异常的发生,可以事先统计剩余存储空间的大小,以作出合理安排。

    4 _0 p) F+ j" z/ j, D  _5 A
    8 e  r( T# s. f. \7 D
    % B. ]6 v% B$ X8 s+ C/ x; Q5 l% ?! v4 z$ X  M
    % ?# W1 M. j- x- V) H  f5 B! a4 R

    " U2 i7 A" T2 M% h& y* h
    ! w! _5 P& X2 P+ l2 a, F0 K
    ) i7 E9 f) t+ v: n# |
    使用道具 举报 回复
    发表于 2016-5-20 09:22:54
    同样遇到了这个问题。
    使用道具 举报 回复 支持 反对
    您需要登录后才可以回帖 登录

    本版积分规则