Android Activity component Startup Process

Source: Internet
Author: User
Tags mremote

1. Step 1 in the general diagram



Step 1 <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4KPHA + expires = "brush: java;"> class ActivityManagerProxy implements IActivityManager {public int startActivity (IApplicationThread caller, Intent intent, String resolvedType, Uri [] grantedUriPermissions, int grantedMode, IBinder resultasks, String res UltWho, int requestCode, boolean onlyIfNeeded, boolean debug) throws RemoteException {Parcel data = Parcel. obtain (); Parcel reply = Parcel. obtain (); data. writeInterfaceToken (IActivityManager. descriptor); data. writeStrongBinder (caller! = Null? Caller. asBinder (): null); intent. writeToParcel (data, 0 );......... data. writeStrongBinder (resulinder); mRemote. transact (START_ACTIVITY_TRANSACTION, data, reply, 0 );}Caller:

final ApplicationThread mAppThread = new ApplicationThread();
It inherits from ApplicationThreadNative, and ApplicationThreadNative inherits from Binder to implement IApplicationThread.

Shows resultasks:



The Parcel and writeStrongBinder methods at the java layer are mapped to the C ++ layer and executed as follows:

~ /Android/frameworks/base/core/jni

---- Android_util_Binder.cpp

Static void android_ OS _Parcel_writeStrongBinder (JNIEnv * env, jobject clazz, jobject object) // clazz Is Parcel, the object points to the hardware Access Service FregService {Parcel * parcel = parcelForJavaObject (env, clazz) created in the Java layer; // gets the reference of the java layer Parcel object data if (parcel! = NULL) {const status_t err = parcel-> writeStrongBinder (ibinderForJavaObject (env, object); if (err! = NO_ERROR) {jniThrowException (env, "java/lang/OutOfMemoryError", NULL );}}}

The implementation of ibinderForjavaObject is as follows:

~ /Android/frameworks/base/core/jni

---- Android_util_Binder.cpp

Sp
 
  
IbinderForJavaObject (JNIEnv * env, jobject obj) {if (obj = NULL) return NULL; if (env-> IsInstanceOf (obj, gBinderOffsets. mClass) {JavaBBinderHolder * jbh = (JavaBBinderHolder *) env-> GetIntField (obj, gBinderOffsets. mObject); // here, the mObject member variable of the obj object is forcibly converted to the JavaBBinderHolder object return jbh! = NULL? Jbh-> get (env): NULL;} if (env-> IsInstanceOf (obj, gBinderProxyOffsets. mClass) {return (IBinder *) env-> GetIntField (obj, gBinderProxyOffsets. mObject);} LOGW ("ibinderForJavaObject: % p is not a Binder object", obj); return NULL ;}
 

(1) If caller. asBinder () is input, a local JavaBBinder object is generated first.

(2) If resultasks are passed in, a proxy object is generated.

The writeStrongBinder implementation is as follows:

~ /Android/frameworks/base/libs/binder

---- Parcel. cpp

status_t Parcel::writeStrongBinder(const sp
 
  & val){    return flatten_binder(ProcessState::self(), val, this);}
 

status_t flatten_binder(const sp
 
  & proc,    const sp
  
   & binder, Parcel* out){    flat_binder_object obj;        obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;    if (binder != NULL) {        IBinder *local = binder->localBinder();        if (!local) {            BpBinder *proxy = binder->remoteBinder();            if (proxy == NULL) {                LOGE("null proxy");            }            const int32_t handle = proxy ? proxy->handle() : 0;            obj.type = BINDER_TYPE_HANDLE;            obj.handle = handle;            obj.cookie = NULL;        } else {            obj.type = BINDER_TYPE_BINDER;            obj.binder = local->getWeakRefs();            obj.cookie = local;        }    } else {        obj.type = BINDER_TYPE_BINDER;        obj.binder = NULL;        obj.cookie = NULL;    }        return finish_flatten_binder(binder, obj, out);}
  
 

(1) if it is a local object, obj. cookie is the IBinder address of the local object.

(2) if it is a proxy object, obj. handle is the handle value of the proxy object.

Step 2

Binder Driver: Call binder_transaction:

~ /Android // kernel/goldfish/drivers/staging/android

---- Binder. c

                case BINDER_TYPE_BINDER:case BINDER_TYPE_WEAK_BINDER: {struct binder_ref *ref;struct binder_node *node = binder_get_node(proc, fp->binder);if (node == NULL) {node = binder_new_node(proc, fp->binder, fp->cookie);......}.......ref = binder_get_ref_for_node(target_proc, node);if (ref == NULL) {return_error = BR_FAILED_REPLY;goto err_binder_get_ref_for_node_failed;}if (fp->type == BINDER_TYPE_BINDER)fp->type = BINDER_TYPE_HANDLE;elsefp->type = BINDER_TYPE_WEAK_HANDLE;fp->handle = ref->desc;......} break;case BINDER_TYPE_HANDLE:case BINDER_TYPE_WEAK_HANDLE: {struct binder_ref *ref = binder_get_ref(proc, fp->handle);......if (ref->node->proc == target_proc) {if (fp->type == BINDER_TYPE_HANDLE)fp->type = BINDER_TYPE_BINDER;elsefp->type = BINDER_TYPE_WEAK_BINDER;fp->binder = ref->node->ptr;fp->cookie = ref->node->cookie;binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL);if (binder_debug_mask & BINDER_DEBUG_TRANSACTION)printk(KERN_INFO "        ref %d desc %d -> node %d u%p\n",       ref->debug_id, ref->desc, ref->node->debug_id, ref->node->ptr);} else {.......}} break;

(1) If it is BINDER_TYPE_BINDER, first create an object and then create a reference object. Handle is the reference handle value.

(2) If it is BINDER_TYPE_HANDLE, first obtain the reference object and then the object. The cookie is the address of the local object IBinder.


Step 3

~ /Android/frameworks/base/core/java/android/app

---- ActivityManagerNative. java

public abstract class ActivityManagerNative extends Binder implements IActivityManager{    ......    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)            throws RemoteException {        switch (code) {        case START_ACTIVITY_TRANSACTION:        {            data.enforceInterface(IActivityManager.descriptor);            IBinder b = data.readStrongBinder();            IApplicationThread app = ApplicationThreadNative.asInterface(b);            Intent intent = Intent.CREATOR.createFromParcel(data);            String resolvedType = data.readString();            ......            IBinder resultTo = data.readStrongBinder();            ......            return true;        }


The Parcel class readStrongBinder is mapped to the C ++ layer and executed as follows:

~ /Android/frameworks/base/core/jni

---- Android_util_Binder.cpp

Static jobject android_ OS _Parcel_readStrongBinder (JNIEnv * env, jobject clazz) {Parcel * parcel = parcelForJavaObject (env, clazz); // obtain a reference to the Java layer reply if (parcel! = NULL) {return javaObjectForIBinder (env, parcel-> readStrongBinder ();} return NULL ;}

~ /Android/frameworks/base/libs/binder

---- Parcel. cpp

sp
 
   Parcel::readStrongBinder() const{    sp
  
    val;    unflatten_binder(ProcessState::self(), *this, &val);    return val;}
  
 

status_t unflatten_binder(const sp
 
  & proc,    const Parcel& in, sp
  
   * out){    const flat_binder_object* flat = in.readObject(false);        if (flat) {        switch (flat->type) {            case BINDER_TYPE_BINDER:                *out = static_cast
   
    (flat->cookie);                return finish_unflatten_binder(NULL, *flat, in);            case BINDER_TYPE_HANDLE:                *out = proc->getStrongProxyForHandle(flat->handle);                return finish_unflatten_binder(                    static_cast
    
     (out->get()), *flat, in);        }            }    return BAD_TYPE;}
    
   
  
 


(1) If it is BINDER_TYPE_BINDER, the local object is returned.

(2) If BINDER_TYPE_HANDLE is used, the proxy object is returned Based on the handle value.


Then execute javaObjectForIBinder.

~ /Android/frameworks/base/core/jni

---- Android_util_Binder.cpp

Jobject javaObjectForIBinder (JNIEnv * env, const sp
 
  
& Val) {if (val = NULL) return NULL; if (val-> checkSubclass (& gBinderOffsets) {// One of our own! Jobject object = static_cast
  
   
(Val. get ()-> object ();........ return object;} // For the rest of the function we will hold this lock, to serialize // looking/creation of Java proxies for native Binder proxies. autoMutex _ l (mProxyLock); // Someone else's... do we know about it? Jobject object = (jobject) val-> findObject (& gBinderProxyOffsets); // check whether a BinderProxy object if (object! = NULL) {// If any returned result is a WeakReference object pointing to the BinderProxy object, that is, a weak reference object jobject res = env-> CallObjectMethod (object, gWeakReferenceOffsets. mGet); // The BinderProxy object pointed to by the weak reference object may be invalid. Therefore, you need to check its validity, the method is to call its member function get to obtain a strongly referenced object. If (res! = NULL) {// if it is not NULL ...... return res; // return directly }..... android_atomic_dec (& gNumProxyRefs); // if it is NULL val-> detachObject (& gBinderProxyOffsets ); // unbind it from an invalid BinderProxy object. env-> DeleteGlobalRef (object); // Delete the global reference of the weak reference object.} object = env-> NewObject (gBinderProxyOffsets. mClass, gBinderProxyOffsets. mConstructor); // create a BinderProxy object if (object! = NULL ){....... env-> SetIntField (object, gBinderProxyOffsets. mObject, (int) val. get (); // BinderProxy. the mObject member variable records the address val-> incStrong (object) of The BpBinder object; // the native object needs to hold a weak reference back to The // proxy, so we can retrieve the same proxy if it is still active. jobject refObject = env-> NewGlobalRef (env-> GetObjectField (object, gBinderProxyOffsets. mSelf); // obtain the member variable mSelf (weak reference object of BinderProxy) in BinderProxy, and then create a global reference object to reference it val-> attachObject (& gBinderProxyOffsets, refObject, jnienv_to_javavm (env), proxy_cleanup); // put it in BpBinder. You can call BpBinder in the previous step when you need to use it next time :: findObj retrieved it. // Note that a new object reference has been created. android_atomic_inc (& gNumProxyRefs); incRefsCreated (env);} return object ;}
  
 

(1) if it is a local object, first convert it to JavaBBinder and then obtain the ActivityRecord object, which inherits IApplicationToken. Stub. IApplicationToken. Stub inherits the Binder and implements IApplicationToken. Therefore, you can convert the image to IBinder.

IBinder resultTo = data.readStrongBinder();

(2) if it is a proxy object, first generate the BinderProxy object. The mObject in it points to the proxy object and converts it to IBinder.

            IBinder b = data.readStrongBinder();            IApplicationThread app = ApplicationThreadNative.asInterface(b);
Then generate the ActivityManagerProxy object, in which mRemote points to the BinderProxy object.

Step 4
~ /Android/frameworks/base/services/java/com/android/server/am

---- ActivityManagerService. java

    public final int startActivity(IApplicationThread caller,            Intent intent, String resolvedType, Uri[] grantedUriPermissions,            int grantedMode, IBinder resultTo,            String resultWho, int requestCode, boolean onlyIfNeeded,            boolean debug) {        return mMainStack.startActivityMayWait(caller, intent, resolvedType,                grantedUriPermissions, grantedMode, resultTo, resultWho,                requestCode, onlyIfNeeded, debug, null, null);    }

To be continued






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.