android SharedPreferences使用技巧

前言

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:2
11-22 09:20:09.159 20370-20370/com.qiyei.javatest D/MainActivity: value 1:2
11-22 09:20:09.159 20370-20370/com.qiyei.javatest D/MainActivity: value 2:2
11-22 09:20:09.159 20370-20370/com.qiyei.javatest D/MainActivity: value 3:2
11-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:2
11-22 09:20:09.175 20370-20370/com.qiyei.javatest D/MainActivity: value 498:2
11-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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值