Android-IPC机制(二)--Bundler、文件共享和Messenger

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);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值