共享文件也是一种不错的进程间通信方式,两个进程通过读/写同一个文件来交换数据,比如A进程把数据写入文件,B进程通过读取这个文件来获取数据。我们知道,在Windows上,一个文件如果被加了排斥锁将会导致其他线程无法对其进行访问,包括读和写,由于Android系统基于Linux,使得其并发读/写可以没有限制地进行,甚至两个线程同时对同一个文件进行写操作都是允许的。通过文件交换数据很好使用,除了可以交换一些文本信息外,我们还可以序列化一个对象到文件系统中的同时从另一个进程中恢复这个对象,下面就展示这种使用方法。
在MainActivity的onResume中序列化一个User对象到sd卡上的一个文件里,然后在SecondActivity的onResume中去反序列化,我们期望在SecondActivity中能够正确地恢复User对象的值。关键代码如下:
//在MainActivity中的修改
private void persistToFile(){
new Thread(new Runnable(){
@Override
public void run(){
User user = new User(1,"Hello world",false);
File dir = new File(MyConstants.CHAPTER_2_PATH);
if(!dir.exists()){
dir.mkdirs();
}
File cachedFile = new File(MyConstants.CACHE_FILE_PATH);
ObjectOutputStream objectOutputStream = null;
try{
objectOutputStream = new ObjectOutputStream(
new FileOutputStream(chacheFile));
objectOutputStream.writeObject(user);
Log.d(TAG,"persist user:" + user);
}catch(IOException e){
e.printStackTrace();
}finally{
MyUtils.close(objectOutputStream);
}
}
}).start();
}
//SecondActivity中的修改
private void recoverFromFile(){
new Thread(new Runnable(){
@Override
public void run(){
User user =null;
File cachedFile = new File(MyConstants.CACHE_FILE_PATH);
if(cachedFile.exists()){
ObjectInputStream objectInputStream = null;
try{
objectInputStream = new ObjectInputStream(
new FileInputStream(chacheFile));
user = (User) objectInputStream.readObject();
Log.d(TAG,"recover user:" + user);
}catch(IOException e){
e.printStackTrace();
}catch (ClassNotFoundException e){
e.printStackTrace();
}finally{
MyUtils.close(objectInputStream);
}
}
}
}).start();
}
log:
很显然,在SecondActivity中成功地从文件恢复了之前存储的User对象的内容,这里之所以说是内容,是因为反序列化得到的对象只是在内容上和序列化之前的对象是一样的,但它们本质上还是两个对象。
文件共享数据对文件格式是没有具体要求的,可以是文本文件,也可以是XML文件,只要读写双发约定数据格式即可。通过文件共享的方式也是有局限性的,比如并发读/写的问题,像上面那个例子,如果并发读/写,那么我们读出的内容就有可能不是最新的,如果是并发写的话那就更严重了。因此我们要尽量避免并发写这种情况的发生或者考虑使用线程同步来限制多个线程的写操作。文件共享方式适合在对数据同步要求不高的进程之间进行通信。
当然,SharedPreference是个特例,众所周知,SharedPreference是Android中提供的轻量级存储方案,它通过键值对的方式来存储数据,在底层实现上它采用XML文件来存储键值对,每个应用的SharedPreference文件都可以在当前包所在的data目录下查看到。一般来说,它的目录位于/data/data/package name/shared_prefs目录下,本质上说,SharedPreference也属于文件的一种,但是由于系统对它的读/写有一定的缓存策略,即在内存中会有一份SharedPreference文件的缓存,因此在多进程模式下,系统对它的读/写就变得不可靠,当面对高并发的读/写访问,SharedPreference有很大几率会丢失数据,因此,不建议在进程通信中使用SharedPreference。