跨進(jìn)程通信的方式有很多,在這里一一展開芯急。
Bundle方式
四大組件都是支持Intent中傳遞Bundle數(shù)據(jù)的菱鸥,所以在啟動(dòng)另一個(gè)進(jìn)程時(shí)候可以通過Intent附加Bundle數(shù)據(jù)進(jìn)行傳遞碑幅,部分場景還可以使用IntentService捍靠,需要注意的是Bundle傳遞的數(shù)據(jù)要序列化膊毁。
文件共享方式
通俗的來講就是兩個(gè)進(jìn)程同時(shí)來讀/寫一個(gè)文件來交換數(shù)據(jù)断序,雖然有風(fēng)險(xiǎn)废睦,但在數(shù)據(jù)不是太頻繁讀和寫還是可以的骚秦,具體的實(shí)現(xiàn)方式就是在一個(gè)進(jìn)程中序列化數(shù)據(jù)到本地碍舍,然后在另一個(gè)進(jìn)程中反序列化既忆,具體實(shí)現(xiàn)方式在前面序列化和反序列化有提到驱负。
Messenger方式
它是可以翻譯為信使,是一種輕量級(jí)的IPC方案患雇,可以傳遞Message對(duì)象跃脊。實(shí)現(xiàn)Messenger分為服務(wù)端和客戶端:
我們先來看服務(wù)端,服務(wù)端代碼如下:
package com.bigaka.service;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.support.annotation.Nullable;
import android.util.Log;
import com.bigaka.Utils.Constants;
/**
* Created by ${luomingjun} on 16/9/24
*
*/
public class MessengerService extends Service{
public static final String TAG="MessengerService";
private static class MessengerHandler extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what)
{
case Constants.MSG_FROM_CLIENT:
Log.e(TAG,"接收的消息來自于客戶端:"+msg.getData().getString("msg"));
break;
default:
super.handleMessage(msg);
}
}
}
private final Messenger mMessenger=new Messenger(new MessengerHandler());
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
}
可以看到我們創(chuàng)建了一個(gè)Service來處理客戶端的連接請(qǐng)求苛吱,同時(shí)創(chuàng)建了一個(gè)Messenger對(duì)象酪术,并從onBind中返回了這個(gè)Messenger,別忘了在Menifest中注冊(cè)這個(gè)Service。
<service android:name="com.bigaka.service.MessengerService"
android:process=":remote"
/>
接下來我們來看客戶端:
package com.bigaka.messenger;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import com.bigaka.Utils.Constants;
import com.bigaka.service.MessengerService;
public class MainActivity extends AppCompatActivity {
private static final String TAG="MainActivity";
private Messenger messenger;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent=new Intent(this, MessengerService.class);
bindService(intent,mConnection, Context.BIND_AUTO_CREATE);
}
private ServiceConnection mConnection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
messenger=new Messenger(service);
Message msg=Message.obtain(null, Constants.MSG_FROM_CLIENT);
Bundle bundle=new Bundle();
bundle.putString("msg","這是從客戶端發(fā)送的消息");
msg.setData(bundle);
try {
messenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(mConnection);
}
}
客戶端綁定了我們剛剛的MessengerService翠储,并從綁定服務(wù)成功的IBinder對(duì)象中創(chuàng)建了一個(gè)Messenger绘雁,并利用Message來send消息。
運(yùn)行起來之后援所,我們可以從日志中看到:
09-24 07:14:46.420 2944-2944/com.bigaka.messenger:remote E/MessengerService: 接收的消息來自于客戶端:這是從客戶端發(fā)送的消息
這種方式只是單向的庐舟,那么我現(xiàn)在希望我給服務(wù)端發(fā)送了一條消息,并且它需要給我回復(fù)一條消息住拭,那又該如何改造我們現(xiàn)在的方法呢挪略?
服務(wù)端:
private static class MessengerHandler extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what)
{
case Constants.MSG_FROM_CLIENT:
Log.e(TAG,"接收的消息來自于客戶端:"+msg.getData().getString("msg"));
Messenger messenger=msg.replyTo;
Message relpyMessage=Message.obtain(null,Constants.MSG_FROM_CLIENT);
Bundle bundle=new Bundle();
bundle.putString("reply","已經(jīng)收到你的消息了历帚,這是回復(fù)你的消息");
relpyMessage.setData(bundle);
try {
messenger.send(relpyMessage);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
super.handleMessage(msg);
}
}
}
客戶端我們需要加一個(gè)Handler來接收消息,如下:
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what)
{
case Constants.MSG_FROM_CLIENT:
Log.e(TAG, "接收的消息來自于服務(wù)端:" + msg.getData().getString("msg"));
break;
default:
super.handleMessage(msg);
}
}
}
private final Messenger mReplyMessenger=new Messenger(new MessengerHandler());
可能會(huì)好奇mReplyMessenger在那個(gè)地方用呢杠娱?注意在客戶端發(fā)送消息時(shí)候挽牢,需要將msg.replyTo=mReplyMessenger;看我們現(xiàn)在的客戶端代碼:
private ServiceConnection mConnection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
messenger=new Messenger(service);
Message msg=Message.obtain(null, Constants.MSG_FROM_CLIENT);
Bundle bundle=new Bundle();
bundle.putString("msg","這是從客戶端發(fā)送的消息");
msg.setData(bundle);
/*** 注意 注意 注意 ***/
msg.replyTo=mReplyMessenger;
try {
messenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
現(xiàn)在我們來運(yùn)行一些,看下Log:
09-24 07:47:13.394 29339-29339/com.bigaka.messenger:remote E/MessengerService: 接收的消息來自于客戶端:這是從客戶端發(fā)送的消息
09-24 07:47:13.771 29311-29311/com.bigaka.messenger E/MainActivity: 接收的消息來自于服務(wù)端:已經(jīng)收到你的消息了摊求,這是回復(fù)你的消息
通信方式就介紹到這里了禽拔,可以擴(kuò)展開來。
以上源碼:https://pan.baidu.com/s/1nv6iqVJ 提取碼:tfpk