IPC Inter-Process Communication 进程间通信或者跨进程通信
Android中最有特色的通信方式 Binder,通过Binder可以轻松地实现进程间通信,除了Binder Android还支持Socket,通过Socket也可以实现任意两个终端之间的通信。一个设备上的两个进程通过Socket通信也是可以的
Android中使用多进程只有一种方法 那就是给四大组件(Activity、Service、Receiver、ContentProvider)在androidMenifest 中指定Android:process属性
android:process=":remote"
进程名以:开头的进程属于当前应用的私有进程,其他应用组件不可以和它跑在同一个进程中。
android:process="com.ryg.chapter_2.remote"
进程名不以:开头的进程属于全局进程,其他应用通过ShareUID 方式可以和它跑在同一个进程中。
一般来说使用多进程会造成如下几个方面的问题
1、静态成员和单例模式完全失效
2、线程同步机制完全失效
3、SharedPreferences的可靠性下降
4、Application 会多次创建
IPC基础概念介绍
1、Serializable接口 Java中的序列化接口
public class User implements Serializable {
private static final long serialVersionUID =132354664544L;
public int userId;
public String username;
public boolean isMale;
.............
}
//序列化过程
User user = new User(0,"jack",true);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("cache.txt"));
out.writeObject(user);
out.close();
//反序列化过程
ObjectInputStream in = new ObjectInputStream(new FileInputStream(“cache.txt”));
User newUser= (User)in.readObject();
in.close();
2、Parcelable Android中的序列化接口
3、Binder
Binder是Android中的一个类,它实现IBinder接口,从IPC角度来说 Binder是Android中的一种跨进程的通信方式,
从Android framework角度来说 Binder是ServiceManager链接各种Manager和相应的ManagerService的桥梁;
从Android 应用层来说 Binder是客户端和服务端通信的媒介。
====================================================================================================================================
Android中的IPC方式
1、使用Bundle
Bundle实现了Parcelable 接口,所以它可以方便的在不同的进程之间进行传输。
2、使用文件共享
Activity1(进程1)
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(cachedFile)); | |
objectOutputStream.writeObject(user); | |
Log.d(TAG, "persist user:" + user); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} finally { | |
MyUtils.close(objectOutputStream); | |
} | |
} | |
}).start(); | |
}
|
|
Activity2 (进程2)
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(cachedFile)); | |
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(); | |
} | |
}
|
|
3、使用Messenger
实现一个Messenger有如下步骤,分为服务端和客户端
a、服务端进程
服务端典型代码,可以看到MessengerHandler 用来处理客户端发送的消息,并从消息中取出客户端发来的文本信息,而mMessenger 是一个Messenger对象,它和MessengerHandler 相关联,并在onBind 方法中返回它里面的Binder对象,可以看出这里Messenger 的作用是将客户端发送的消息传递给MessengerHandler处理。
public class MessengerService extends Service {
| |
private static final String TAG = "MessengerService"; | |
private static class MessengerHandler extends Handler { | |
@Override | |
public void handleMessage(Message msg) { | |
switch (msg.what) { | |
case MyConstants.MSG_FROM_CLIENT: | |
Log.i(TAG, "receive msg from Client:" + msg.getData().getString("msg")); | |
Messenger client = msg.replyTo; | |
Message relpyMessage = Message.obtain(null, MyConstants.MSG_FROM_SERVICE); | |
Bundle bundle = new Bundle(); | |
bundle.putString("reply", "嗯,你的消息我已经收到,稍后会回复你。"); | |
relpyMessage.setData(bundle); | |
try { | |
client.send(relpyMessage); | |
} catch (RemoteException e) { | |
e.printStackTrace(); | |
} | |
break; | |
default: | |
super.handleMessage(msg); | |
} | |
} | |
} | |
private final Messenger mMessenger = new Messenger(new MessengerHandler()); | |
@Override | |
public IBinder onBind(Intent intent) { | |
return mMessenger.getBinder(); | |
} | |
@Override | |
public void onCreate() { | |
super.onCreate(); | |
} | |
@Override | |
public int onStartCommand(Intent intent, int flags, int startId) { | |
return super.onStartCommand(intent, flags, startId); | |
} | |
}
客户端实现
public class MessengerActivity extends Activity {
private static final String TAG = "MessengerActivity";
private Messenger mService;
private Messenger mGetReplyMessenger = new Messenger(new MessengerHandler());
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MyConstants.MSG_FROM_SERVICE:
Log.i(TAG, "receive msg from Service:" + msg.getData().getString("reply"));
break;
default:
super.handleMessage(msg);
}
}
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
mService = new Messenger(service);
Log.d(TAG, "bind service");
Message msg = Message.obtain(null, MyConstants.MSG_FROM_CLIENT);
Bundle data = new Bundle();
data.putString("msg", "hello, this is client.");
msg.setData(data);
msg.replyTo = mGetReplyMessenger;
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
public void onServiceDisconnected(ComponentName className) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messenger);
Intent intent = new Intent("com.ryg.MessengerService.launch");
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
unbindService(mConnection);
super.onDestroy();
}
}
4、使用AIDL
........
|