IPC进程间通信简介
1.在AndroidManifest.xml中声明组件android:process属性。
不指定process属性,则默认运行在主进程中,主进程名字为包名。
android:process = package:remote,将运行在package:remote进程中,属于全局进程,其他具有相同shareUID与签名的APP可以跑在这个进程中。
android:process = :remote ,将运行在默认包名:remote进程中,而且是APP的私有进程,不允许其他APP的组件来访问。
2.多进程引发的问题
· 静态成员和单例失效:每个进程保持各自的静态成员和单例,相互独立。
· 线程同步机制失效:每个进程有自己的线程锁。
· SharedPreferences可靠性下降:不支持并发写,会出现脏数据。
· Application多次创建:不同进程跑在不同虚拟机,每个虚拟机启动会创
建自己的Application,自定义Application时生命周期会混乱。
综上,不同进程拥有各自独立的虚拟机,Application,内存空间,由此引发一系列问题。
3.进程间通信
Bundle/Intent传递数据:
可传递基本类型,String,实现了Serializable或Parcellable接口的数据结构。Serializable是Java的序列化方法,Parcellable是Android的序列化方法,前者代码量少(仅一句),但I/O开销较大,一般用于本地文件存取和网络传输;Parcellable稍复杂,但效率高,一般用于内存间序列化和反序列化传输。
4.优缺点
优点:简单易用。
缺点:不适合高并发场景,无法做到进程间即时通信。
适用场景:交换简单数据,无并发访问情形和实时性不高的场景。
文件共享实现自定义对象的存取
1.首先自定义对象需要实现Serializable接口,serialVersionUID保证了序列化和反序列化出来的是相同的两个对象
package com.example.myfileshare;
import java.io.Serializable;
public class Book implements Serializable {
public static final long serialVersionUID = 123456789123456789L;
private int bookId;
private String bookName;
public Book(int bookId, String bookName) {
this.bookId = bookId;
this.bookName = bookName;
}
//getter和setter方法
}
2.写入文件可从文件读取的方法,模拟器运行找不到文件,真机测试顺利存取。
//写入文件
private void writeToFile() {
new Thread() {
@Override
public void run() {
Book book = new Book(1, "android");
//文件夹路径
String path = Environment.getExternalStorageDirectory().getPath() + "/cache/";
File f = new File(path);
if (!f.exists()) {
f.mkdirs();
}
//文件路径
File cacheFile = new File(path + "book.txt");
ObjectOutputStream out = null;
try {
out = new ObjectOutputStream(new FileOutputStream(cacheFile));
//写入对象
out.writeObject(book);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
//从文件读取出对象
private void readFromFile() {
new Thread(new Runnable() {
@Override
public void run() {
String path = Environment.getExternalStorageDirectory().getPath() + "/cache/";
File cacheFile = new File(path + "book.txt");
if (cacheFile.exists()) {
ObjectInputStream in = null;
Book book = null;
try {
in = new ObjectInputStream(new FileInputStream(cacheFile));
book = (Book) in.readObject();
mTextView.setText(book.getBookName());
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
}