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

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

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

    [LV.2]偶尔看看I

    107

    主题

    1246

    帖子

    4394

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    4394
    发表于 2016-5-17 17:53:20
    出错堆栈3 W4 A2 }6 b3 T: Y0 T
    [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)   
    
    9 V' V. L% r( k; I& M) Q# V4 M
    ! i4 ~* e, M' O# _
    【出错代码】
    * U, H$ \/ \4 P5 E3 A% F
    类:me.bfbrmt.bugly2.MainActivity
    22.png
    - J& u0 ?# S; n$ H3 J' ~9 m' C: d3 V
    代码片段(第40行):9 X& ]  b" T4 m+ b9 f9 u$ t

    # J& g% [. I( A+ ^; E1 X【出错原因】
    * h5 a) _4 ^& w0 P5 ~
    从异常的完整描述:
    “android.database.sqlite.SQLiteFullException: database or disk is full (code 13)”
    很容易看出,这是因为数据库的体积达到最大限制或者磁盘已满。也就是说数据量太大,或者磁盘空间不足。

    4 A9 G- @0 j& x: d5 X
    分析:
    注意第 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 D5 S. k. y5 \+ i; ?; u
    【解决方案】
    % q. Y+ ?, g' [* v3 q! c) ]* z/ G7 F7 x5 Z
    ; K& K5 W8 k: D5 c, h8 k
    1. 如果是由于限制了数据库最大体积导致的,如果条件允许,可以考虑放松限制。如果这个数据库是别人提供的,那么可以使用 getMaximumSize 获取当前最大容量。
    2. 如果是手机剩余存储空间不足导致的,则可以提醒用户清理垃圾,腾出内部空间。如果是并不敏感的数据,比如并不敏感的缓存数据,可以考虑放到 SD 卡中去。如果数据量非常大,比如视频缓存,更应该考虑放到 SD 卡中去。若是要避免此类异常的发生,可以事先统计剩余存储空间的大小,以作出合理安排。

    $ d1 P& S# j% z( {4 P& X9 h/ a& d2 A

      n+ c" e- ], Z2 I5 L
    9 Q4 j$ w  r+ S  E" I' s- W  u
    , p: {7 w. T! J9 A6 j5 Z3 x, N" I# E4 J: I% D- H

    ! M' _' f$ Y  O" V" a+ O. V( r
    4 o5 ?) f- d- Y
    使用道具 举报 回复
    发表于 2016-5-20 09:22:54
    同样遇到了这个问题。
    使用道具 举报 回复 支持 反对
    您需要登录后才可以回帖 登录

    本版积分规则