标签:
Android中的Activity、Service和Receiver都是支持在 Intent 中传递 Bundle 数据的,Bundle实现了 Parcelable 接口,它可以方便的在不同进程间传输。当我们在一个进程中启动了另一个进程的 Activity、Service 和 Receiver,就可以在 Bundle 中附加需要传输给远程进程的信息并通过 Intent 发送。注意:传输的数据必须能够被序列化,比如基本数据类型、实现Serializable 或 Parcelable接口的对象以及Android支持的特殊对象。
考虑这么一种情况,A进程正在计算,计算完成后它要启动B进程的一个组件并把计算结果传递给B进程,可是这个计算结果不支持放入Bundle中,因此无法使用Intent来传输。可以这么考虑来解决:通过Intent启动进程B的一个Service组件(比如IntentService),让Service在后台进行计算,计算完毕后再启动B进程中真正要启动的目标组件,由于Service也运行在B进程中,所有目标组件就可以直接获取计算结果。
文件共享的方式要注意并发的问题,考虑使用线程同步来限制多个线程的写操作。
//MainActivity.java
private void persistToFile() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                User user = new User(1, "hello", true);
                File dir = new File(getFilesDir().getAbsolutePath() + File.separator + "User");
                if (!dir.exists())
                    dir.mkdir();
                File cacheFile = new File(getFilesDir().getAbsolutePath() + File.separator + "User" + File.separator + "usercache");
                ObjectOutputStream objectOutputStream = null;
                try {
                    objectOutputStream = new ObjectOutputStream(new FileOutputStream(cacheFile));
                    objectOutputStream.writeObject(user);
                    Log.d("MainActivity", "persist user: " + user);
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (objectOutputStream != null) {
                        try {
                            objectOutputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }).start();
    }
//SecondActivity
private void recoverFromFile() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                User user = null;
                File cacheFile = new File(getFilesDir().getAbsolutePath() + File.separator + "User" + File.separator + "usercache");
                ObjectInputStream objectInputStream = null;
                try {
                    objectInputStream = new ObjectInputStream(new FileInputStream(cacheFile));
                    user = (User) objectInputStream.readObject();
                    Log.d("SecondActivity", "recover user" + user);
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                } finally {
                }
            }
        }).start();
    }
    public Messenger(Handler target) {
        mTarget = target.getIMessenger();
    }
    public Messenger(IBinder target) {
        mTarget = IMessenger.Stub.asInterface(target);
    }
(1)服务端进程 
在服务端创建一个Service来处理客户端的连接请求,同时创建一个Handler并通过它来创建一个Messenger对象,然后在Service的 onBind 中返回这个Messenger 对象底层的 Binder 即可。 
(2)客户端进程 
客户端进程中,首先要绑定服务端的Service,绑定成功后用服务端返回的 IBinder 对象创建一个Message对象 。 如果需要服务端能够回应客户端,需要创建一个Handler并创建一个新的Messenger,并把这个Messenger对象通过Message的replyTo参数传递给服务端,服务端通过这个replay参数就可以回应客户端。下面看两个例子:  
 
(1)服务端接受客户端发送的消息
服务端代码,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.d(TAG, "receive msg from Client:" + 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 messenger.getBinder();
    }
}
客户端代码,首先要绑定远程的Messenger,绑定成功后,根据服务端返回的Binder对象创建Messenger对象,并使用此对象向服务端发送消息。
public class MessengerActivity extends AppCompatActivity {
    private static final String TAG = "MessengerActivity";
    private Messenger mServiece;
    private ServiceConnection coon = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            mServiece = new Messenger(iBinder);
            Message msg = Message.obtain();
            Bundle data = new Bundle();
            data.putString("msg", "hello, this is client");
            msg.setData(data);
            try {
                mServiece.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_messenger);
        Intent intent = new Intent(this, MessengerService.class);
        bindService(intent, coon, BIND_AUTO_CREATE);
    }
    @Override
    protected void onDestroy() {
        unbindService(coon);
        super.onDestroy();
    }
}
log
com.example.mac.processdemo:remote D/MessengerService: receive msg from Client:hello, this is client
在Messenger中进行数据传递必须将数据放入Message中,而Messenger和Message都实现了Parcelable接口,因此可以跨进程传输。
(2)服务端接受客户端接受的消息,并向客户端做出回应
服务端代码,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.d(TAG, "receive msg from Client: " + msg.getData().getString("msg"));
                    Messenger client = msg.replyTo;
                    Message replyMessage = Message.obtain(null,MyConstants.MSG_FROM_SERVICE);
                    Bundle bundle = new Bundle();
                    bundle.putString("reply","收到了来自客户端的消息");
                    replyMessage.setData(bundle);
                    try {
                        client.send(replyMessage);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }
    private final Messenger messenger = new Messenger(new MessengerHandler());
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return messenger.getBinder();
    }
}
客户端,也需要准备一个接收消息的Messenger和Handler,注意:当客户端发送消息时,需要把接收服务端回复的Messenger通过Message的replayTo参数传递给服务端
public class MessengerActivity extends AppCompatActivity {
    private static final String TAG = "MessengerActivity";
    private Messenger mServiece;
    private Messenger mGetReplayMessenger = new Messenger(new MessengerHandler());
    private ServiceConnection coon = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            mServiece = new Messenger(iBinder);
            Message msg = Message.obtain();
            Bundle data = new Bundle();
            data.putString("msg", "hello, this is client");
            msg.setData(data);
            /**
             *  注意:当客户端发送消息时,需要把接收服务端回复的Messenger通过Message的replayTo参数传递给服务端
             */
            msg.replyTo = mGetReplayMessenger;
            try {
                mServiece.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_messenger);
        Intent intent = new Intent(this, MessengerService.class);
        bindService(intent, coon, BIND_AUTO_CREATE);
    }
    @Override
    protected void onDestroy() {
        unbindService(coon);
        super.onDestroy();
    }
    private static class MessengerHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MyConstants.MSG_FROM_SERVICE:
                    Log.d(TAG, "receive msg from Service: " + msg.getData().getString("reply"));
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }
}Android中的IPC方式(一)—— Bundle、文件共享、Messenger
标签:
原文地址:http://blog.csdn.net/young_xiaot/article/details/51357045