1. Using Bundles
The activity, service, and receiver in Android support the delivery of bundle data in Intent, and the bundle implements the Parcelable interface, which can be conveniently transferred between different processes. When we start the Activity, Service, and Receiver of another process in one process, we can attach to the Bundle the information that needs to be transferred to the remote process and send it through Intent. Note: Transmitted data must be able to be serialized, such as basic data types, objects that implement serializable or parcelable interfaces, and special objects supported by Android.
Consider a situation in which a process is being calculated, after which it starts a component of the B process and passes the result of the calculation to the B process, but this calculation is not supported in the bundle and therefore cannot be transmitted using intent. This can be resolved by intent starting a service component of process B (such as Intentservice), allowing the service to be evaluated in the background, and then starting the target component in the B process that is actually started, since the service is also running in the B process. All target components can directly get the results of the calculation.
2. sharing files using file Sharing is also a good way to communicate between processes, and two incoming cars exchange data by reading/writing the same file. In the Android system, you can read/write files concurrently, and even two threads can read/write to the same file at the same time. You can also serialize an object to the file system while recovering the object in another process. The key code is as follows:
File sharing is a way to pay attention to concurrency issues, and consider using thread synchronization to limit write operations for multiple threads.
//mainactivity.javaPrivate void Persisttofile() {NewThread (NewRunnable () {@Override Public void Run() {User user =NewUser (1,"Hello",true); File dir =NewFile (Getfilesdir (). GetAbsolutePath () + File.separator +"User");if(!dir.exists ()) Dir.mkdir (); File Cachefile =NewFile (Getfilesdir (). GetAbsolutePath () + File.separator +"User"+ File.separator +"Usercache"); ObjectOutputStream ObjectOutputStream =NULL;Try{ObjectOutputStream =NewObjectOutputStream (NewFileOutputStream (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 (); }
//secondactivityPrivate void Recoverfromfile() {NewThread (NewRunnable () {@Override Public void Run() {User user =NULL; File Cachefile =NewFile (Getfilesdir (). GetAbsolutePath () + File.separator +"User"+ File.separator +"Usercache"); ObjectInputStream ObjectInputStream =NULL;Try{ObjectInputStream =NewObjectInputStream (NewFileInputStream (Cachefile)); user = (user) objectinputstream.readobject (); LOG.D ("Secondactivity","Recover User"+ user); }Catch(IOException e) {E.printstacktrace (); }Catch(ClassNotFoundException e) {E.printstacktrace (); }finally{}}}). Start (); }
The use of Messengermessenger can be translated as a messenger, through which you can pass the message object in different processes, in the message to put the data to be passed, it is easy to achieve the process of data transfer. Messenger is a lightweight IPC scheme that implements the Parcelable interface and the underlying implementation is aidl. This can be seen from the way it is constructed:
publicMessenger(Handler target) { mTarget = target.getIMessenger(); }
publicMessenger(IBinder target) { mTarget = IMessenger.Stub.asInterface(target); }
There are several steps to implementing a Messenger, divided into server and client
(1) service-side process
Create a service on the server to handle the client's connection request, create a handler and create a Messenger object from it, and then return the Binder at the bottom of the Messenger object in service Onbind.
(2) Client process
In the client process, the service side is bound first, and the binding succeeds and a Message object is created with the IBinder object returned by the server. If the server needs to be able to respond to the client, a handler is created and a new messenger is created, and the Messenger object is passed to the server via the ReplyTo parameter of message, and the server can respond to the client through this replay parameter. Let's look at two examples:
(1) The server accepts messages sent by the client
The server-side code, Messengerhandler, is used to process the messages sent by the client and to remove the textual information from the message from the client. And Mmessenger is a Messenger object that is associated with Messengerhandler and returns the Binder object inside it in the Onbind method, as you can see, the role of Messenger here is to send the message to the client Passed to Messengerhandler processing.
Public class messengerservice extends Service { Private Static FinalString TAG ="Messengerservice";Private Static class messengerhandler extends Handler { @Override Public void Handlemessage(Message msg) {Switch(msg.what) { CaseMYCONSTANTS.MSG_FROM_CLIENT:LOG.D (TAG,"Receive msg from Client:"+ Msg.getdata (). GetString ("MSG")); Break;default:Super. Handlemessage (msg); } } }Private FinalMessenger Mmessenger =NewMessenger (NewMessengerhandler ());@Nullable @Override PublicIBinderOnbind(Intent Intent) {returnMessenger.getbinder (); }}
Client code, first to bind the remote Messenger, after the binding succeeds, the Messenger object is created based on the binder object returned by the server and uses this object to send a message to the server.
Public class messengeractivity extends appcompatactivity { Private Static FinalString TAG ="Messengeractivity";PrivateMessenger mserviece;PrivateServiceconnection Coon =NewServiceconnection () {@Override Public void onserviceconnected(ComponentName componentname, IBinder IBinder) {mserviece =NewMessenger (IBinder); Message msg = Message.obtain (); Bundle data =NewBundle (); 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 =NewIntent ( This, Messengerservice.class); Bindservice (Intent, Coon, bind_auto_create); }@Override protected void OnDestroy() {unbindservice (coon);Super. OnDestroy (); }}
Log
fromthisis client
Data passing in Messenger must put the data in a message, and Messenger and message implement the Parcelable interface, so they can be transferred across processes.
(2) The server accepts the message received by the client and responds to the client
Service-side code, Messengerhandler receive a message, immediately reply to a message to the client
Public class messengerservice extends Service { Private Static FinalString TAG ="Messengerservice";Private Static class messengerhandler extends Handler { @Override Public void Handlemessage(Message msg) {Switch(msg.what) { CaseMYCONSTANTS.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 =NewBundle (); Bundle.putstring ("Reply","received a message from the client"); Replymessage.setdata (bundle);Try{client.send (replymessage); }Catch(RemoteException e) {E.printstacktrace (); } Break;default:Super. Handlemessage (msg); } } }Private FinalMessenger Messenger =NewMessenger (NewMessengerhandler ());@Nullable @Override PublicIBinderOnbind(Intent Intent) {returnMessenger.getbinder (); }}
Client, we also need to prepare a messenger and handler to receive the message, note: When the client sends a message, it needs to pass the messenger of the receiving server reply through the Replayto parameter of the message to the server.
Public class messengeractivity extends appcompatactivity { Private Static FinalString TAG ="Messengeractivity";PrivateMessenger mserviece;PrivateMessenger Mgetreplaymessenger =NewMessenger (NewMessengerhandler ());PrivateServiceconnection Coon =NewServiceconnection () {@Override Public void onserviceconnected(ComponentName componentname, IBinder IBinder) {mserviece =NewMessenger (IBinder); Message msg = Message.obtain (); Bundle data =NewBundle (); Data.putstring ("MSG","Hello, this is client"); Msg.setdata (data);/** * Note: When a client sends a message, the messenger that receives the server reply is passed to the server via the Replayto parameter of the message */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 =NewIntent ( 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) { CaseMYCONSTANTS.MSG_FROM_SERVICE:LOG.D (TAG,"Receive msg from Service:"+ Msg.getdata (). GetString ("Reply")); Break;default:Super. Handlemessage (msg); } } }}
IPC Mode in Android (i)--bundle, file sharing, Messenger