美文网首页Android进阶学习
Android-IPC机制(二)--Bundler、文件共享和M

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

作者: Jack_Ou | 来源:发表于2021-01-29 14:39 被阅读0次

    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);
    

    相关文章

      网友评论

        本文标题:Android-IPC机制(二)--Bundler、文件共享和M

        本文链接:https://www.haomeiwen.com/subject/wivqtltx.html