为什么文件操作会阻止SharedPreferences的提交

时间:2013-12-16 10:31:06

标签: android file sharedpreferences

解决!这只是我手机的一个问题,与代码或Android平台无关。

我遇到了一个关于Android中SharedPreferences的奇怪问题。如果你能帮助我,我将不胜感激。

问题是,当我在SharedPreferences提交之前进行大量文件操作时,提交会花费很多时间来阻止我的活动。这是测试,onResume方法在SharedPreferences提交几秒钟时被阻止:

/*
 * Only this method was modified in the new created test project,
 * so there is nothing else can interfere with the results.
 */
protected void onResume()
{
    super.onResume();

    long s = System.currentTimeMillis();
    deleteDatabase( "test.db" );
    Log.d( "xw", "Step 1. At: " + (System.currentTimeMillis() - s) );
    File dbFile = getDatabasePath( "test.db" );
    Log.d( "xw", "Step 2. At: " + (System.currentTimeMillis() - s) );
    dbFile.getParentFile().mkdir();
    Log.d( "xw", "Step 3. At: " + (System.currentTimeMillis() - s) );
    InputStream is = null;
    OutputStream os = null;
    try
    {
        dbFile.createNewFile();
        AssetManager ass = getAssets();
        is = ass.open( "db" + File.separator + "test.db", AssetManager.ACCESS_STREAMING );
        os = new FileOutputStream( dbFile );
        int bytesReaded;
        byte[] buf = new byte[1024];
        while ( (bytesReaded = is.read( buf )) != -1 )
            os.write( buf, 0, bytesReaded );
        Log.d( "xw", "DB prepared. At: " + (System.currentTimeMillis() - s) );
    } 
    catch ( IOException e )
    {
        e.printStackTrace();
        return;
    }
    finally
    {
        try
        {
            if ( is != null )
                is.close();
            if ( os != null )
                os.close();
        } 
        catch ( IOException e2 ) 
        {
            e2.printStackTrace();
        }
    }
    Log.d( "xw", "End of file copying. At: " + (System.currentTimeMillis() - s) );

    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( MainActivity.this );
    Log.d( "xw", "Before commit. At: " + (System.currentTimeMillis() - s) );
    prefs.edit().putInt( "test", prefs.getInt( "test", -1 ) + 1 ).commit();
    Log.d( "xw", "After commit. At: " + (System.currentTimeMillis() - s) );

    Log.d( "xw", "===========================================" );
}

我已经尝试了几次测试,发现重型文件操作可能是原因。结果(部分但典型)在这里:

// Only commit the SharedPreferences. 
Before commit. At: 0
After commit. At: 26
===========================================
Before commit. At: 0
After commit. At: 15
===========================================

// Only copy a large file (31MB).
Step 1. At: 1
Step 2. At: 1
Step 3. At: 1
DB prepared. At: 1268
End of file copying. At: 1271
===========================================
Step 1. At: 44
Step 2. At: 44
Step 3. At: 44
DB prepared. At: 1159
End of file copying. At: 1162
===========================================
Step 1. At: 16698
Step 2. At: 16699
Step 3. At: 16700
DB prepared. At: 17943
End of file copying. At: 17946
===========================================
Step 1. At: 4285
Step 2. At: 4285
Step 3. At: 4286
DB prepared. At: 5472
End of file copying. At: 5474
===========================================

// Only copy a small file (900KB).
Step 1. At: 4
Step 2. At: 4
Step 3. At: 5
DB prepared. At: 44
End of file copying. At: 45
===========================================
Step 1. At: 1
Step 2. At: 1
Step 3. At: 2
DB prepared. At: 38
End of file copying. At: 38
===========================================

// Copy a large file (31MB) first and then commit the SharedPreferences.
Step 1. At: 0
Step 2. At: 0
Step 3. At: 3
DB prepared. At: 1292
End of file copying. At: 1294
Before commit. At: 1295
After commit. At: 24206
===========================================
Step 1. At: 67
Step 2. At: 67
Step 3. At: 68
DB prepared. At: 1521
End of file copying. At: 1522
Before commit. At: 1523
After commit. At: 13743
===========================================
Step 1. At: 3605
Step 2. At: 3606
Step 3. At: 3607
DB prepared. At: 4820
End of file copying. At: 4823
Before commit. At: 4823
After commit. At: 24229
===========================================

// Copy a small file (900KB) first and then cimmit the SharedPreferences.
Step 1. At: 4
Step 2. At: 5
Step 3. At: 5
DB prepared. At: 77
End of file copying. At: 78
Before commit. At: 78
After commit. At: 89
===========================================
Step 1. At: 6
Step 2. At: 6
Step 3. At: 6
DB prepared. At: 46
End of file copying. At: 46
Before commit. At: 47
After commit. At: 542
===========================================
Step 1. At: 4
Step 2. At: 5
Step 3. At: 6
DB prepared. At: 50
End of file copying. At: 50
Before commit. At: 51
After commit. At: 61
===========================================

我甚至试图将文件一次复制两次(第一个日志和第二个日志用“-------”分隔):

// Copy a large file (31MB) for twice at once.
Step 1. At: 1
Step 2. At: 2
Step 3. At: 2
DB prepared. At: 1475
End of file copying. At: 1477
-------------------------------------------
Step 1. At: 1
Step 2. At: 1
Step 3. At: 1
DB prepared. At: 1126
End of file copying. At: 1129
===========================================
Step 1. At: 50
Step 2. At: 51
Step 3. At: 51
DB prepared. At: 1256
End of file copying. At: 1258
-------------------------------------------
Step 1. At: 15098
Step 2. At: 15099
Step 3. At: 15099
DB prepared. At: 16245
End of file copying. At: 16249
===========================================
Step 1. At: 8073
Step 2. At: 8079
Step 3. At: 8083
DB prepared. At: 9268
End of file copying. At: 9271
-------------------------------------------
Step 1. At: 2995
Step 2. At: 2996
Step 3. At: 2997
DB prepared. At: 4183
End of file copying. At: 4186
===========================================

// Copy a small file (900KB) for twice at once.
Step 1. At: 1
Step 2. At: 1
Step 3. At: 1
DB prepared. At: 33
End of file copying. At: 34
-------------------------------------------
Step 1. At: 1
Step 2. At: 1
Step 3. At: 2
DB prepared. At: 32
End of file copying. At: 33
===========================================
Step 1. At: 2
Step 2. At: 2
Step 3. At: 2
DB prepared. At: 43
End of file copying. At: 43
-------------------------------------------
Step 1. At: 1
Step 2. At: 2
Step 3. At: 2
DB prepared. At: 45
End of file copying. At: 47
===========================================

如果我将SharedPreferences的操作放在文件操作之前,那么可能性也会阻止文件操作。此外,在我的应用程序中,虽然数据库已准备好(复制到应该存在的位置并且IO流已关闭),但是当SharedPreferences的提交被阻止时,无法从中获取数据。

似乎复制大文件的文件确实不稳定且难以理解。

我花了很多时间来解决这个问题,但仍然不知道。真的需要你的帮助! 3Q〜

2 个答案:

答案 0 :(得分:1)

SharedPreferences.Editor.commit()在设计上是同步的。

如果您想要异步写入并且不关心是否成功,请使用apply()

此外,UI线程不是执行大量文件I / O的正确位置。

答案 1 :(得分:0)

此问题与代码或Android平台无关。这只是我手机的问题。我已经在其他手机中测试了我的代码并且它们都正常运行。我不知道这是我手机的硬件问题还是修改后的Android平台问题,但显然这不是一般问题。