Android: inter-process communication

Source: Internet
Author: User

Android: inter-process communication

Intent ComponentName broadcast-BroadcastReceiver ContentProvider AIDL

ComponentName of Intent

Intent is our most commonly used data transmission channel, especially opening an Activity through Intent, so everyone will be familiar with it. We usually use Intent to open the internal Activity of the same process (App). To achieve cross-process communication, we need to send the Intent object to another App, and parse it out, then ComponentName is required to do this for us. Since data can be sent to another process, interaction between different processes can be realized.
Note: To enable Activity B in another process, set the exported of the Activity to true in the AndroidManifest file of Project B. Otherwise, an error is reported.

android:exported="true"

The constructor that will use ComponentName is as follows:

    public ComponentName(String pkg, String cls) {        if (pkg == null) throw new NullPointerException("package name is null");        if (cls == null) throw new NullPointerException("class name is null");        mPackage = pkg;        mClass = cls;    }

It requires two parameters. The first parameter is an existing pakage (package), and the second parameter is the name of the class you want to open in this package (note that it includes the complete package name ), the following is an example:
MainActivity in the AndroidAIDL (com. example. androidaidl) Process

@ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); // receives the passed Intent if (getIntent ()! = Null) {System. out. println ("----------" + getIntent (). getIntExtra ("id", 0) + "----------");}}

Another process, AndroidTest, writes the following code in MainActivity:

/** Specify the name of the Activity with the package name */ComponentName componentName = new ComponentName ("com. example. androidaidl "," com. example. androidaidl. mainActivity "); Intent intent = new Intent (); intent. putExtra ("id", 1001); intent. setComponent (componentName); startActivity (intent );

After running the above Code, you will see that 1001 is printed in LogCat, indicating that the Intent sent from the AndroidTest process is normal.

Note: In the code above, we pass the basic data type. for basic data types, such as Int and String, you can directly read the data as above, however, if a complex object is sent, the object must implement the Serializable or Parcelable interface.
For example, we define a SendData object as the passing object, which implements the Parcelable interface:

public class SendData implements Parcelable{    int id;    String content;    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getContent() {        return content;    }    public void setContent(String content) {        this.content = content;    }    public static final Parcelable.Creator
  
    CREATOR = new Parcelable.Creator
   
    () {        @Override        public SendData createFromParcel(Parcel source) {            // TODO Auto-generated method stub            SendData data = new SendData();            data.setId(source.readInt());            data.setContent(source.readString());            return data;        }        @Override        public SendData[] newArray(int size) {            // TODO Auto-generated method stub            return new SendData[size];        }    };    @Override    public int describeContents() {        // TODO Auto-generated method stub        return 0;    }    @Override    public void writeToParcel(Parcel dest, int flags) {        // TODO Auto-generated method stub        dest.writeInt(id);        dest.writeString(content);    }}
   
  

Sending code:

Intent intent = new Intent (); SendData data = new SendData (); data. setId (1001); data. setContent ("hellow world"); // sends the serialized object intent. putExtra ("data", data); startActivity (intent );

Receive code

Protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); if (getIntent ()! = Null) {if (getIntent (). getParcelableExtra ("data") = null) return; // read the serialized object and convert it to SendData type SendData data = (SendData) getIntent (). getParcelableExtra ("data"); System. out. println ("----------" + data. getContent () + "-----------");}}

If you are in the same process, the above method has no problems. If you are in different processes, pay attention to it,The package name of the SendData bean must be the same in each project.Otherwise, the receiver cannot be parsed.

Broadcast-BroadcastReceiver

Android broadcast is system-level. As long as the same Action is passed (Action_Test is used in the following example), messages broadcast by other processes can be received, data can be transmitted through Intent in broadcast.

Sender code:

Intent intent = new Intent("Action_Test");SendData data = new SendData();data.setId(1001);data.setContent("hellow world");intent.putExtra("data", data);intent.putExtra("id", 1001);getActivity().sendBroadcast(intent);

Receiver code (Dynamic register broadcast ):

innerReceiver = new InnerReceiver();IntentFilter filter = new IntentFilter("Action_Test");registerReceiver(innerReceiver, filter);class InnerReceiver extends BroadcastReceiver{    @Override    public void onReceive(Context context, Intent intent) {        // TODO Auto-generated method stub        if (intent.getAction().equals("Action_Test")){            SendData data = (SendData)intent.getParcelableExtra("data");            System.out.println("-----------"+data.getContent()+"------------");        }    }   }

Because data is transmitted through Intent, the requirements for complex objects are the same as those for the first method, requiring the same package name of the bean

ContentProvider

ContentProvider is usually used to operate datasets. Android itself provides a lot of ContentProvider access, such as contacts and albums.
To access ContentProvider, you must use Uri and start with "content. Let's take a look at the usage:
In the process AndroidAIDL (com. example. androidaidl), we define a class inherited from ContentProvider and need to reload its method. Here we take query as an example.

Public class ProviderTest extends ContentProvider {private static final UriMatcher MATCHER = new UriMatcher (UriMatcher. NO_MATCH); static {// Add the access string, corresponding to the android: authorities attribute MATCHER in the configuration file. addURI ("com. mh. getdata "," stock ", 10001) ;}@ Override public boolean onCreate () {// TODO Auto-generated method stub return false ;} @ Override/*** @ param uri URI path * @ param projection the column set to be protected. If null is passed, all columns will be included in Remove. * @ param selection is used to filter the dataset rules. null indicates that the dataset is not filtered. * @ param selectionArgs is formatted like a string. Can the selection parameter contain? S, which will be replaced by the content of selectionArgs * @ param sortOrder sorting. */public Cursor query (Uri uri, String [] projection, String selection, String [] selectionArgs, String sortOrder) {// TODO Auto-generated method stub System. out. println ("-------------------- query --------------------"); return null ;}@ Override public String getType (Uri uri) {// TODO Auto-generated method stub return null ;} @ Override public Uri insert (Uri uri, ContentValues values) {// TODO Auto-generated method stub return null;} @ Override public int delete (Uri uri, String selection, string [] selectionArgs) {// TODO Auto-generated method stub return 0;} @ Override public int update (Uri uri, ContentValues values, String selection, String [] selectionArgs) {// TODO Auto-generated method stub return 0 ;}}

After defining this class, you must declare it in AndroidManifest,Android: exported = true, Remember to write, otherwise a permission error will be prompted

        
                      
  

The preceding configuration has two attributes:
Android: name is the class name
Android: authorities: This is the Uri mentioned above. You need to access the Provider through this Uri.

Let's take a look at the caller. In another process, we have the following code:

ContentResolver resolver = getActivity (). getContentResolver ();/** com. mh. getdata/stock must be consistent with the Uri added in the process where the Provider is located */Uri uri = Uri. parse ("content: // com. mh. getdata/stock "); Cursor cursor = resolver. query (uri, null, null );

After the above Code is called, the "query" text is printed in LogCat. The table name Provider is successfully called, and we can interact with the Provider object in the AndroidAIDL process through resolver.

AIDL

An Interface Definition Language. Android automatically generates communication code. With AIDL, we can call methods in another process in one process, it is said that some big companies use the AIDL to keep their services alive, so we can study them well. I personally think that AIDL is more suitable for plug-in systems, or multiple apps can form a system. For example, due to memory leakage, some companies encapsulate WebView into an app separately, you can use the AIDL technology to call the interface in this app to operate WebView behavior.
The following describes how to use it:
Create a common File in two projects (new-> General-> File in Eclipse). Remember to write the suffix (aidl) at the same time ), the package names of the files in the two projects must be the same and the content must be the same,


After compilation, a file with the same name and suffix of java is automatically generated under the gen directory. There is the Stub class we will use.

public static abstract class Stub extends android.os.Binder implements com.example.aidl.AidlFunctions

In the interface file AIDLFunctions. aidl, we define a method named show

interface AidlFunctions{    void show();}

Server:
The use of AIDL requires a Service, so we need to declare a Service on the server.

Public class AIDLService extends Service {// stub is the AidlFunctions automatically generated by the system. stub binder; @ Override public void onCreate () {// TODO Auto-generated method stub super. onCreate () ;}@ Override public IBinder onBind (Intent intent) {// TODO Auto-generated method stub binder = new AidlFunctions. stub () {@ Override // here is the implementation of the method declared in the interface public void show () throws RemoteException {// TODO Auto-generated method stub System. out. println ("-------------------- received ----------------------") ;}; return binder ;}}

Declare Service in AndroidManifest

        
              
                               
           
  

Client:

// To bind a service, you must use ServiceConnection private ServiceConnection serviceConnection; // custom interface, which is the same as private AidlFunctions aidlFunctions; serviceConnection = new ServiceConnection () {@ Override public void onServiceDisconnected (ComponentName name) {// TODO Auto-generated method stub System. out. println ("-------------------- ServiceDisconnected --------------------") ;}@ Override public void onServiceConnected (ComponentName, IBinder service) {// TODO Auto-generated method stub System. out. println ("-------------------- ServiceConnected ----------------------"); aidlFunctions = AidlFunctions. stub. asInterface (service) ;}}; Intent intent = new Intent ("com. example. androidaidl. AIDLService "); bindService (intent, serviceConnection, Context. BIND_AUTO_CREATE); // call the show method try {aidlFunctions. show ();} catch (RemoteException e) {// TODO Auto-generated catch block e. printStackTrace ();}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.