android SharedPreferences使用技巧

来源:互联网 发布:淘宝红包链接 编辑:程序博客网 时间:2024/05/16 20:27

前言

android中我们经常用SharedPreferences来存储数据,关于其基本用法我这里就不介绍了,下面介绍几个使用技巧

1 SharedPreferences一次性存储大量数据可以采用事务

有时我们需要一次性的存入大量的数据,比如存储500个数据,这时如果我们不采用事务,每次调用SharedPreferences.Editor 的putXxx()方法后,调用SharedPreferences.Editor 的commit()方法来提交,这样往往会导致UI线程比较慢,因为commit()是同步的,往往会比较耗时。正确的做法是采用“事务”,即先put完数据,最后一次性提交。可以参考下面的例子
public class MainActivity extends AppCompatActivity {    private final static String TAG = "MainActivity";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        put();        get();    }    private void put(){        SharedPreferences preferences = getSharedPreferences("test",MODE_PRIVATE);        SharedPreferences.Editor editor = preferences.edit();        for (int i = 0 ; i < 500 ; i++){            editor.putInt("key" + i,2);        }        editor.commit();    }    private void get(){        SharedPreferences preferences = getSharedPreferences("test",MODE_PRIVATE);        for (int i = 0 ; i < 500 ; i++){            String key = "key" + i;            Log.d(TAG,"value " + i +":" +preferences.getInt(key,0));        }    }

程序运行输出结果为:

11-22 09:20:09.159 20370-20370/com.qiyei.javatest D/MainActivity: value 0:211-22 09:20:09.159 20370-20370/com.qiyei.javatest D/MainActivity: value 1:211-22 09:20:09.159 20370-20370/com.qiyei.javatest D/MainActivity: value 2:211-22 09:20:09.159 20370-20370/com.qiyei.javatest D/MainActivity: value 3:211-22 09:20:09.159 20370-20370/com.qiyei.javatest D/MainActivity: value 4:2。。。。。。。。。。11-22 09:20:09.175 20370-20370/com.qiyei.javatest D/MainActivity: value 497:211-22 09:20:09.175 20370-20370/com.qiyei.javatest D/MainActivity: value 498:211-22 09:20:09.175 20370-20370/com.qiyei.javatest D/MainActivity: value 499:2

如果我们把代码中的editor.putInt("key" + i,2);改成editor.putInt("key" + i,2).commit();就会发现,存储会耗费大量的时间,从而阻塞主线程。

2 用SharedPreferences.Editor 的apply()来代替commit()

上面的例子我们可以改成如下:

public class MainActivity extends AppCompatActivity {        private final static String TAG = "MainActivity";        @Override        protected void onCreate(Bundle savedInstanceState) {            super.onCreate(savedInstanceState);            setContentView(R.layout.activity_main);            put();            get();        }        private void put(){            SharedPreferences preferences = getSharedPreferences("test",MODE_PRIVATE);            SharedPreferences.Editor editor = preferences.edit();            for (int i = 0 ; i < 500 ; i++){                editor.putInt("key" + i,2).apply();            }            //editor.commit();        }        private void get(){            SharedPreferences preferences = getSharedPreferences("test",MODE_PRIVATE);            for (int i = 0 ; i < 500 ; i++){                String key = "key" + i;                Log.d(TAG,"value " + i +":" +preferences.getInt(key,0));            }        }}

改成这样,我们运行,发现也很快,不会造成主线程阻塞。我们查看源代码发现:

        /**         * Commit your preferences changes back from this Editor to the         * {@link SharedPreferences} object it is editing.  This atomically         * performs the requested modifications, replacing whatever is currently         * in the SharedPreferences.         *         * <p>Note that when two editors are modifying preferences at the same         * time, the last one to call commit wins.         *         * <p>If you don't care about the return value and you're         * using this from your application's main thread, consider         * using {@link #apply} instead.         *         * @return Returns true if the new values were successfully written         * to persistent storage.         */        boolean commit();        /**         * Commit your preferences changes back from this Editor to the         * {@link SharedPreferences} object it is editing.  This atomically         * performs the requested modifications, replacing whatever is currently         * in the SharedPreferences.         *         * <p>Note that when two editors are modifying preferences at the same         * time, the last one to call apply wins.         *         * <p>Unlike {@link #commit}, which writes its preferences out         * to persistent storage synchronously, {@link #apply}         * commits its changes to the in-memory         * {@link SharedPreferences} immediately but starts an         * asynchronous commit to disk and you won't be notified of         * any failures.  If another editor on this         * {@link SharedPreferences} does a regular {@link #commit}         * while a {@link #apply} is still outstanding, the         * {@link #commit} will block until all async commits are         * completed as well as the commit itself.         *         * <p>As {@link SharedPreferences} instances are singletons within         * a process, it's safe to replace any instance of {@link #commit} with         * {@link #apply} if you were already ignoring the return value.         *         * <p>You don't need to worry about Android component         * lifecycles and their interaction with <code>apply()</code>         * writing to disk.  The framework makes sure in-flight disk         * writes from <code>apply()</code> complete before switching         * states.         *         * <p class='note'>The SharedPreferences.Editor interface         * isn't expected to be implemented directly.  However, if you         * previously did implement it and are now getting errors         * about missing <code>apply()</code>, you can simply call         * {@link #commit} from <code>apply()</code>.         */        void apply();

通过注释我们发现,如果在主线程中使用commit(),android推荐我们使用apply()来代替,我们可以知道,apply()是异步的,并不会马上执行,往往是采用子线程的形式去执行的。因此上面的代码我们可以采用apply()来代替commit()

3 总结

SharedPreferences往往在Android用来保存一些配置信息或者一些用户权限等,如果要存储获取读取大量数据,需要注意阻塞主线程的问题。
0 0
原创粉丝点击