AsInterface parsing in Binder, binderasinterface

Source: Internet
Author: User

AsInterface parsing in Binder, binderasinterface

When AIDL is used for communication, an asInterface function is generated in Stub class. The example in Android development art exploration is analyzed. The source code of the asInterface function is:

 1         /** 2          * Cast an IBinder object into an com.willhua.demoaidl.aidl.IBookManager 3          * interface, generating a proxy if needed. 4          */ 5         public static com.willhua.demoaidl.aidl.IBookManager asInterface( 6                 android.os.IBinder obj) { 7             if ((obj == null)) { 8                 return null; 9             }10             android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);11             if (((iin != null) && (iin instanceof com.willhua.demoaidl.aidl.IBookManager))) {12                 return ((com.willhua.demoaidl.aidl.IBookManager) iin);13             }14             return new com.willhua.demoaidl.aidl.IBookManager.Stub.Proxy(obj);15         }

 

We know that asInterface is used to return different instance objects based on whether the call belongs to the same process,However, many children's shoes may not be very clear about how the process is implemented and what is returned. I will share my understanding on this issue.Obviously, the Code shows that the key to determining which object to return is the return result of obj. queryLocalInterface (DESCRIPTOR.

Next we will use the actual DEMO to understand the process. The Code is based on the example in Android development art exploration.

There are two main things in the DEMO: MainActivity and BookService. MainActivity goes to bind BookService, and BookService sets android in Manifest: process to run the same process and process as MainActivity respectively.

Main Code:

public class BookService extends Service {    private Binder mBinder = new IBookManager.Stub() {    ...    };        @Override    public IBinder onBind(Intent intent) {        // TODO Auto-generated method stub        LOG("BookService onBind mBinder:" +mBinder.getClass().getName() + " Process:" + Process.myPid());        return mBinder;    }}
public class MainActivity extends Activity{    private IBookManager mService;    private Button mQuery;    private TextView mOutInfo;        ...        @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        connectService();    }        private void connectService(){        Intent intent = new Intent(getApplicationContext(), BookService.class);        bindService(intent, new ServiceConnection() {                        @Override            public void onServiceDisconnected(ComponentName name) {                // TODO Auto-generated method stub                            }                        @Override            public void onServiceConnected(ComponentName name, IBinder service) {                // TODO Auto-generated method stub                LOG("onServiceConnected " + service);                mService = IBookManager.Stub.asInterface(service);            }        }, BIND_AUTO_CREATE);            }    ...}

    public static abstract class Stub extends android.os.Binder implements            com.willhua.demoaidl.aidl.IBookManager {        private static final java.lang.String DESCRIPTOR = "com.willhua.demoaidl.aidl.IBookManager";        /** Construct the stub at attach it to the interface. */        public Stub() {            this.attachInterface(this, DESCRIPTOR);        }        /**         * Cast an IBinder object into an com.willhua.demoaidl.aidl.IBookManager         * interface, generating a proxy if needed.         */        public static com.willhua.demoaidl.aidl.IBookManager asInterface(                android.os.IBinder obj) {            if ((obj == null)) {                return null;            }            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);            if (((iin != null) && (iin instanceof com.willhua.demoaidl.aidl.IBookManager))) {                return ((com.willhua.demoaidl.aidl.IBookManager) iin);            }            return new com.willhua.demoaidl.aidl.IBookManager.Stub.Proxy(obj);        }...}

Some source code of androd. OS. Binder:

public class Binder implements IBinder {    //...    /**     * Convenience method for associating a specific interface with the Binder.     * After calling, queryLocalInterface() will be implemented for you     * to return the given owner IInterface when the corresponding     * descriptor is requested.     */    public void attachInterface(IInterface owner, String descriptor) {        mOwner = owner;        mDescriptor = descriptor;    }        /**     * Use information supplied to attachInterface() to return the     * associated IInterface if it matches the requested     * descriptor.     */    public IInterface queryLocalInterface(String descriptor) {        if (mDescriptor.equals(descriptor)) {            return mOwner;        }        return null;    }        //...        final class BinderProxy implements IBinder {        //...                public IInterface queryLocalInterface(String descriptor) {        return null;        }                //...    }}    

 

Through the LOG, we found that in the onServiceConnected function, if MainActivity and BookService are in the same process, the printed log is:

 

If the MainActivity is different from the BookService process, and the MainActivity is bound to the BookService service across processes, the printed log is:

 

Analyze the same process first,

In the same process, the type of the service object received by onServiceConnected is BookServices $1. We know that $ represents the internal class in BookServices, and in the definition of BookServices, we only defined an IBookManager in the initialization of mBinder. the subclass of Stub (), that is, IBookManager received in onServiceConnected during the same process. stub () type. The queryLocalInterface method of IBookManager. Stub () extenders android. OS. Binder implements IBookManager comes from the superclass android. OS. Binder. For the descriptor passed in the method, we can see through the asInterface code that it is the DESCRIPTOR defined in Stub, while the mDescriptor defined in the Binder is assigned in the attachInterface function, the attachInterface function is called in the Stub constructor.

this.attachInterface(this, DESCRIPTOR);

The call in onServiceConnected is:

mService = IBookManager.Stub.asInterface(service);

Note that sercice is IBookManager. Stub, so that we can know that,

if (mDescriptor.equals(descriptor))

If both the mDescriptor and descriptor in the statement are the DESCRIPTOR defined in IBookManager. Stub, queryLocalInterface returns mOwer. So what is mOwer? Careful kids shoes may already know the answer. When the Stub constructor calls attachInterface, it has assigned a value to mOwer and assigned this value, that is, the Stub object itself! Back to the logic of asInterface, we can conclude that when the process is the same, the returned result of calling asInterface is the Stub object, which is actually the mBinder returned in onBind.

Analyze the situation of cross-process calls

The preceding log shows that the service received in onSericeConnected is android during cross-Process calling. OS. the BinderProxy type, and the source code above has been given, BinderProxy is the final class, and its queryLocalInterface method directly returns null, combined with the asInterface code logic, it will know that it returns IBookManager. stub. proxy object. It is concluded that Stub is returned when the asInterface is called during the same process. proxy object.

At this point, the question mentioned in the beginning should be clear. However, another new question is raised: Why does onServiceConnected receive OS. BinderProxy during cross-process scheduling, while IBookManager. Stub is received when the same process is called?

Listen again...

 

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.