1.Bundle
我们知道,Acitivity、Service和Receiver都是通过Bundle进行通信的,所有的Intent.putExtra()方法最终都会分装到Bundle中,而Bundle实现了Parcelable接口,所以可以很方便的在进程间进行通信。
所以我们可以通过Intent启动进程B的一个Service组件(例如IntentService,JobService,JobIntentService),执行后台计算,计算完成之后,由于这个Service在进程B中,所以进程B可以直接处理计算结果。
1.1 JobIntentService用法
// IntentService被废弃了,就不举例了
// 进程内使用Bundle传输数据
public class MyIntentService extends JobIntentService {
private static final String TAG = MyIntentService.class.getSimpleName();
static final int JOB_ID = 1000;
public MyIntentService() {
}
//暴露给Activity发送需要执行的耗时任务
public static void enqueueWork(Context context, Intent work) {
enqueueWork(context, MyIntentService.class, JOB_ID, work);
}
// 处理耗时任务
@Override
protected void onHandleWork(@NonNull Intent intent) {
Log.e(TAG, "Executing work: " + intent);
String label = intent.getStringExtra("label");
if (label == null) {
label = intent.toString();
}
toast("Executing: " + label);
for (int i = 0; i < 5; i++) {
Log.i(TAG, "Running service " + (i + 1)
+ "/5 @ " + SystemClock.elapsedRealtime());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
Log.e(TAG, "Completed service @ " + SystemClock.elapsedRealtime());
Log.e(TAG, "label: " + label +", current thread :" + Thread.currentThread());
}
final Handler mHandler = new Handler(Looper.getMainLooper()){
@Override
public void handleMessage(Message msg) {
Toast.makeText(MyIntentService.this, (String)msg.obj, Toast.LENGTH_SHORT).show();
super.handleMessage(msg);
}
};
void toast(final CharSequence text) {
Message msg = mHandler.obtainMessage();
msg.obj = text.toString();
mHandler.sendMessage(msg);
}
}
// 主线程发送任务
Intent intent = new Intent();
intent.putExtra("label","1");
MyIntentService.enqueueWork(this,intent);
1.2 JobService用法
// jobService服务
public class MyJobService extends JobService {
private static final String TAG = MyJobService.class.getSimpleName();
private Messenger mActivityMessenger;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
mActivityMessenger = intent.getParcelableExtra(MESSENGER_INTENT_KEY);
return START_NOT_STICKY;
}
@Override
public boolean onStartJob(final JobParameters params) {
//执行任务
// 如果还有任务没有执行完就返回true
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
sendMessage(MSG_COLOR_STOP, params.getJobId());
return false;
}
private void sendMessage(int messageID, @Nullable Object params) {
// 把消息回送到发送者
Message m = Message.obtain();
m.what = messageID;
m.obj = params;
try {
mActivityMessenger.send(m);
} catch (RemoteException e) {
Log.e(TAG, "Error passing service object back to activity.");
}
}
}
// 发送消息
mServiceComponent = new ComponentName(this, MyJobService.class);
JobInfo.Builder builder = new JobInfo.Builder(mJobId++, mServiceComponent);
// 设置策略
.....
// 设置数据
PersistableBundle extras = new PersistableBundle();
String workDuration = mDurationTimeEditText.getText().toString();
// 安排执行任务
JobScheduler tm = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
tm.schedule(builder.build());
2. 文件共享
文件共享的方式实现进程间通信,主要实现就是进程A通过把序列化的对象写入到文件中,在进程B通过ObjectInputStream来将对象读取出来。具体实现demo将上一讲的序列化和反序列化的测试代码。2.1 Serializable序列化对象
3. Messager
Messager是一种轻量级的IPC方案,其底层实现也是基于AIDL。从如下代码可以证明Messager是基于AIDL实现的,通过传入的IBinder对象拿到服务端代理。
// 客户端初始化用
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
//服务端初始化用
//Handler实现了Messager的服务端IMessenger.Stub
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
服务端实现
public class MessengerService extends Service {
private static final int MESSAGE_FROM_CLIENT = 1;
private static final int MESSAGE_TO_CLIENT = 2;
private final Messenger messager = new Messenger(new MessagerHandler());
private static class MessagerHandler extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_FROM_CLIENT:
Log.i("JackOu",msg.getData().getString("data"));
// 如果要回复,拿到客户端的Messager代理在发送回去
Messenger messenger = msg.replyTo;
Message message = Message.obtain(null, MESSAGE_TO_CLIENT);
Bundle bundle = new Bundle();
bundle.putString("reply", "hello client");
message.setData(bundle);
try {
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
super.handleMessage(msg);
}
}
}
@Override
public IBinder onBind(Intent intent) {
return messager.getBinder();
}
}
客户端实现
private ServiceConnection messengerSconn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mMessenger = new Messenger(service);
Message msg = Message.obtain(null, 1);
Bundle bundle = new Bundle();
bundle.putString("data","hello world!");
msg.setData(bundle);
msg.replyTo = clientMessenger; // 如果需要服务端回复需要把自己的处理器发过去
try {
mMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
// 绑定服务端
Intent intentMessenger = new Intent(this, MessengerService.class);
bindService(intentMessenger, messengerSconn, Context.BIND_AUTO_CREATE);
网友评论