Android IPC Aidl use (iii)---System aidl call

Source: Internet
Author: User
Tags mremote

Android IPC Aidl use (iii)-system AIDL call
Aidl use of the Android IPC (i) –aidl common use
Aidl use of Android IPC (ii)-AIDL local implementation

Aidl's understanding:

IBinder in the service
Remember that we used the new imyinterface.stub () up in MyService to IBinder and then return in the Onbind method. Then let's look at Imyinterface.stub:

publicstaticabstractclass Stub extends android.os.Binder implements aidl.IMyInterface {..........}

As you can see, the stub is a static abstract class in IMyInterface, inherits the binder, and implements the IMyInterface interface. This explains why we need to implement imyinterface in the definition of imyinterface.stub, and also explains why we can transform imyinterface.stub upward into ibinder.

The IMyInterface in activity
In activity, through Serviceconnection connection MyService and successful callback onserviceconnected we send back IBinder through IMyInterface.Stub.asInterface (service) conversion to IMyInterface, let's see how this can be converted:

 Public Static Abstract  class Stub extends android. os. Binder Implements aidl. IMyInterface {.......... Public StaticAidl. IMyInterfaceAsinterface(Android.os.IBinder obj) {if(obj = =NULL)) {return NULL; }//Check binder is not in the current processAndroid.os.IInterface iin = obj.querylocalinterface (descriptor);if(((Iin! =NULL) && (iininstanceofAidl. IMyInterface)) {return(Aidl.    IMyInterface) iin); }return NewAidl. IMyInterface.Stub.Proxy (obj);}}

First, what we should understand is that the IBinder returned is the IBinder we return in the service's Onbind () method, and then we call the static method in the stub asinterface and pass in the IBinder when the argument is returned.
In the Asinterface method, it is first judged whether the incoming IBinder is NULL, if NULL returns a null, and then the IBinder is not in the current process, if so, then return directly to IMyInterface, If not, return to IMyInterface.Stub.Proxy (obj). Here I think it is necessary to understand that the direct return of the imyinterface is the implementation of the defined interface method getinfor. Because of what is implemented in Imyinterface.stub. Of course, if it is in the same process, then we call the method of IMyInterface in the local call method, directly call on it.

If it is not in the same process, it will return IMyInterface.Stub.Proxy (obj):

 Private Static  class Proxy implements aidl. IMyInterface {        PrivateAndroid.os.IBinder Mremote;        Proxy (Android.os.IBinder remote) {mremote = remote; }@Override         PublicAndroid.os.IBinderAsbinder() {returnMremote; } PublicJava.lang.StringGetinterfacedescriptor() {returnDescriptor; }@Override         PublicJava.lang.Stringgetinfor(java.lang.String s)throwsandroid.os.RemoteException {Android.os.Parcel _data = Android.os.Parcel.obtain ();            Android.os.Parcel _reply = Android.os.Parcel.obtain (); Java.lang.String _result;Try{_data.writeinterfacetoken (descriptor); _data.writestring (s);//Transfer data to a remoteMremote.transact (Stub.transaction_getinfor, _data, _reply,0); _reply.readexception ();//Accept data returned from the remote_result = _reply.readstring (); }finally{_reply.recycle ();            _data.recycle (); }return_result; }    }Static Final intTransaction_getinfor = (Android.os.IBinder.FIRST_CALL_TRANSACTION +0);}

In the proxy, we first successfully return the service connection ibinder its internal variable mremote, here to mention, here IBinder or MyService Onbind returned. Then, when we call the IMyInterface method, is actually called the Proxy method, which is why this class is called Porxy reason.

When calling Imyinterface.getinfor (String s), we look at the getinfor in the proxy, first obtained two parcel objects _data, _data, from the variable name can be seen, one is to transmit data, The other is to accept the return data. Next, write the descriptor (that is, the full name of the class) to the _data, and then write the method parameters. And then there's the most important step,

Mremote.transact (Stub.transaction_getinfor, _data, _reply, 0);
Here we call the IBinder Transact method to pass the data to the remote server. Then in our remote MyService, the stub in the inside Will callback Ontransact () (because you send the data to a remote service, the remote service receives the data will be callback)

Note: This is called in the remote service.

@Overridepublic BooleanOntransact (intCode, Android.os.Parcel data, android.os.Parcel reply,intFlagsthrowsandroid.os.RemoteException {Switch(code) { CaseInterface_transaction: {reply.writestring (descriptor);return true; } CaseTransaction_getinfor: {data.enforceinterface (descriptor); Java.lang.String _arg0;//Remove Parameters_arg0 = Data.readstring ();//Remote service calls its own locally implemented method to get the return valueJava.lang.String _result = This. Getinfor (_ARG0); Reply.writenoexception ();//write return valueReply.writestring (_result);return true; }    }return Super. Ontransact (Code, data, reply, flags);}

The Ontransact method is implemented inside the stub.

Let's take a look at its four parameters:
code: Each method has a number of type int to differentiate (swicth in the back), in our case the stub.transaction_getinfor in our proxy.
Data : This is a pass-through that contains our parameters, as well as the description of the class.
Reply: Returns the data that we want to write whether the exception has occurred, and the return value
Flags: Whether the method has a return value and 0 indicates a return value.

Call ontransact means that there is data coming, first of all through SWICTH to determine which method, and then take out the method parameters, call the local implementation of the method to get the return value, write the return value to reply. Finally, returns true to send the data out, playing false will not return the results to the activity. This means that only return true, we can accept the data returned from the remote.

       //传送数据到远程的        0);        _reply.readException();       //接受从远端传回的数据        _result = _reply.readString();
Using the system's Aidl (get Android Cache)

Remember the first time you did not graduate when you do a mobile phone anti-virus software inside is the use of aidl to achieve, directly using someone else to write a good aidl file.

New package Name: ANDROID.CONTENT.PM, and copy the 3 files.

Your project is considered a client to enable cross-process communication.

Use the following:

 PackageCom.losileeya.systemaidl;ImportAndroid.content.pm.IPackageDataObserver;ImportAndroid.content.pm.IPackageStatsObserver;ImportAndroid.content.pm.PackageInfo;ImportAndroid.content.pm.PackageManager;ImportAndroid.content.pm.PackageStats;ImportAndroid.os.Bundle;ImportAndroid.os.Handler;ImportAndroid.os.RemoteException;Importandroid.support.v7.app.AppCompatActivity;ImportAndroid.text.format.Formatter;ImportAndroid.util.Log;ImportAndroid.view.View;ImportAndroid.widget.Button;ImportAndroid.widget.TextView;ImportAndroid.widget.Toast;ImportJava.lang.reflect.Method;ImportJava.util.List; Public  class mainactivity extends appcompatactivity  implements  View. Onclicklistener {    PrivateTextView tvshowcaches, Tvappcache;PrivateButton Btnscancache, Btnclearall;PrivatePackagemanager pm; StringBuilder SB =NewStringBuilder (); StringBuilder Sbcache =NewStringBuilder ();Private LongCacheS; Handler Mhadler =NewHandler ();@Override    protected void onCreate(Bundle savedinstancestate) {Super. OnCreate (Savedinstancestate);        Setcontentview (R.layout.activity_main);        Btnscancache = (Button) Findviewbyid (R.id.btn_scancache);        Btnclearall = (Button) Findviewbyid (R.id.btn_clearall);        Tvshowcaches = (TextView) Findviewbyid (r.id.tv_showappinfo);        Tvappcache = (TextView) Findviewbyid (R.id.tv_appcache); Sbcache.append ("all caches: \ n");        Tvappcache.settext (Sbcache.tostring ()); Btnscancache.setonclicklistener ( This); Btnclearall.setonclicklistener ( This); }@Override     Public void OnClick(View v) {CacheS =0;if(V.getid () = = Btnscancache.getid ()) {getcaches ();//========== get the cache for each app}Else if(V.getid () = = Btnclearall.getid ())            {Cleanall (v);        Getcaches (); }} class Mypackagestateobserver extends Ipackagestatsobserver.stub {@Override         Public void ongetstatscompleted(Packagestats pstats,BooleanSUCCEEDED)throwsremoteexception {String PackageName = pstats.packagename;LongCacheSize = pstats.cachesize;LongCodesize = pstats.codesize;LongDataSize = pstats.datasize; CacheS + = CacheSize;//Sb.delete (0, Sb.length ());            if(CacheSize >0) {Sb.append ("PackageName ="+ PackageName +"\ n"). Append ("CacheSize:"+ CacheSize +"\ n"). Append ("DataSize:"+ DataSize +"\ n"). Append ("-----------------------\ n")                ; LOG.E ("AAAA", sb.tostring ()); }}} class Clearcacheobj extends Ipackagedataobserver.stub {@Override         Public void onremovecompleted(String PackageName,Final BooleanSUCCEEDED)throwsremoteexception {mhadler.post (NewRunnable () {@Override                 Public void Run() {Toast.maketext (Getapplicationcontext (),"Clear Status:"+ succeeded, Toast.length_short). Show ();        }            }); }    }/** * Clean all app Cache Click events * * @param View */     Public void Cleanall(View view) {//freestorageandnotifyMethod[] methods = PackageManager.class.getMethods (); for(Method method:methods) {if("Freestorageandnotify". Equals (Method.getname ())) {Try{Method.invoke (PM, Long.max_value,NewClearcacheobj ()); }Catch(Exception e)                {E.printstacktrace (); }return; }        }    }Private void getcaches() {//ScanPM = Getpackagemanager (); list<packageinfo> packages = Pm.getinstalledpackages (0);intmax = Packages.size ();intCurrent =0; Sb.delete (0, Sb.length ()); Sb.append ("All installed app information: \ n"); Sb.append ("All apps Combined:"+ Max +"\ n"); Tvshowcaches.settext (Sb.tostring ()); for(PackageInfo pinfo:packages) {String PackageName = pinfo.packagename;Try{Method Getpackagesizeinfo = Packagemanager.class. Getdeclaredmethod ("Getpackagesizeinfo", String.class, Ipackagestatsobserver.class); Getpackagesizeinfo.invoke (PM, PackageName,NewMypackagestateobserver ());            current++; }Catch(Exception e)                {current++;            E.printstacktrace (); }        }//=== here, data ready to completeMhadler.postdelayed (NewRunnable () {@Override             Public void Run() {Toast.maketext (Getapplicationcontext (),"Cache information Get Done", Toast.length_short). Show (); Sbcache.append (Formatter.formatfilesize (Getapplicationcontext (), CacheS) +"\ n");                Tvshowcaches.settext (Sb.tostring ());                Tvappcache.settext (Sbcache.tostring ()); Sbcache.delete (0, Sbcache.length ()); }        }, +);//ok, all application information display complete}}

Through the Aidl method to obtain the application's cache information, Getpackagesizeinfo is a private method inside the Packagemanager,

We can call it through reflection, and this method will pass a Ipackagestatsobserver.stub object.

Use reflection Clearcacheobj after Freestorageandnotify method

The effect is as follows:

Demo Portal: Aidlmaster

More study materials:
Android: Learn aidl, this article is enough (UP)
Android: Learn aidl, this article is enough (next)
Service:binder,messenger,aidl in Android

Android IPC Aidl use (iii)---System aidl call

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.