最近须要写个Demo,对咱们公司的SDK作测试,因此遇到这么个问题,记录一下。java
SDK是运行在额外的进程的Service的,内部对数据库和SharePreference有操做,咱们想测试的时候,直接修改其数据库和SharePreference中的值,从而可以很方便的完成一些功能上的测试,结果发现失败了,缘由居然是:Sharepreference在多进程读写的状况下,不能跨进程同步。android
写个例子验证一下:数据库
首先定义两个Activity,分别是Activity_A和Activity_B,代码相似,都是对同一个Sharepreference进行读写操做。只是两个运行在不一样的进程。app
Activity_A的代码以下:ide
package com.tjz.sp.test; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.widget.TextView; import com.example.tjz.imageswitcher.R; public class SharePrefTestActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_share_pref_test); } /** * 写入sharepreference * @param view */ public void onWriteClick(View view){ SpUtil.put(this,"按钮A事件写入"); } /** * 读入sharepreference,并显示 * @param view */ public void onReadClick(View view){ String result = SpUtil.get(this); result = TextUtils.isEmpty(result)?"null":result; TextView tv = (TextView) findViewById(R.id.tv_result); tv.setText(result); } public void onStartClick(View view){ Intent intent = new Intent(this,SharePrefTestBActivity.class); startActivity(intent); } }
Activity_B代码以下:工具
package com.tjz.sp.test; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.view.View; import android.widget.TextView; import com.example.tjz.imageswitcher.R; public class SharePrefTestBActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_share_pref_test_b); } /** * 写入sharepreference * @param view */ public void onWriteClick(View view){ SpUtil.put(this,"按钮B事件写入"); } /** * 读入sharepreference,并显示 * @param view */ public void onReadClick(View view){ String result = SpUtil.get(this); result = TextUtils.isEmpty(result)?"null":result; TextView tv = (TextView) findViewById(R.id.tv_result); tv.setText(result); } }
除了Activity_A多了一个可以启动Activity_B的方法外,两者几乎同样。布局
Activity_A与B的布局也相似,就不贴代码了 ,直接放个图:测试
Manifest文件中配置以下:this
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.tjz.imageswitcher"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name="com.tjz.sp.test.SharePrefTestActivity" android:label="SP_A"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.tjz.sp.test.SharePrefTestBActivity" android:label="SP_B" android:process=":newprocess"> </activity> </application> </manifest>
须要注意的是Activity_B配置了process属性为newprocess。code
Sharepreference操做工具类:
package com.tjz.sp.test; import android.content.Context; import android.content.SharedPreferences; /** * Created by Tjz on 2016/10/9. */ public class SpUtil { private static final String SP_NAME = "com.tjz.sp"; private static final String SP_KEY = "key"; public static void put(Context context, String value){ SharedPreferences sp =context.getSharedPreferences(SP_NAME,Context.MODE_PRIVATE); sp.edit().putString(SP_KEY,value).commit(); } public static String get(Context context){ SharedPreferences sp =context.getSharedPreferences(SP_NAME,Context.MODE_PRIVATE); return sp.getString(SP_KEY,null); } }
而后看图:
程序最开始启动时,Activity_A读取到sharepreference中为null,这没问题,
而后Activity_A向Sharepreference中写入值,并读取,也没问题:
接下来,启动Activity_B,而且读取Sharepreference,结果也正确:
而后Activity_B写入本身的值,并读取,也没问题:
接下来就是回到Activity_A中,再读取一次Sharepreference,发现值并无改变:
强行停止这个应用,再次启动Activity_A,读取Sharepreference,发现值已经改变为当初Activity_B写入的值。
因而可知,每一个进程都维护了本身的一份Sharepreference副本,在其运行过程当中,与其余进程彻底没有关系,只有应用结束时,才会将本身的修改持久化到文件系统中。
之后再讨论,进程对Sharepreference所作的修改是在这个进程终止时写入文件仍是在整个应用终止时才写入。