• StartActivity的内部代码实现原理


    [在此处输入文章标题]

     

     

    最近研究Android,把StartActiviy的流程研究了一下,特结合代码与大家分享:

    1.  首先调用ActivitystartActivity-1表示 target Activity finish的时候不通知original Activity

      public void startActivity(Intent intent) {
            startActivityForResult(intent, -1);
        }

    2 . 调用ActivitydstartActivityForResult方法, Instrumentation class 里面有一个ActivityMonitor  的内部类,用来监控viewsystem的交互

      public void startActivityForResult(Intent intent, int requestCode) {
            if (mParent == null) {
                Instrumentation.ActivityResult ar =
                    mInstrumentation.execStartActivity(
                        this, mMainThread.getApplicationThread(), mToken, this,
                        intent, requestCode);
                if (ar != null) {
                    mMainThread.sendActivityResult(
                        mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                        ar.getResultData());
                }
                if (requestCode >= 0) {
                    // If this start is requesting a result, we can avoid making
                    // the activity visible until the result is received.  Setting
                    // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
                    // activity hidden during this time, to avoid flickering.
                    // This can only be done when a result is requested because
                    // that guarantees we will get information back when the
                    // activity is finished, no matter what happens to it.
                    mStartedActivity = true;
                }
            } else {
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }

    3. 调用Instrumentation class ExecStartActivity

     public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode) {
            IApplicationThread whoThread = (IApplicationThread) contextThread;

          // 如果找到匹配的Activityam.mHits++
            if (mActivityMonitors != null) {
                synchronized (mSync) {
                    final int N = mActivityMonitors.size();
                    for (int i=0; i<N; i++) {
                        final ActivityMonitor am = mActivityMonitors.get(i);
                        if (am.match(who, null, intent)) {
                            am.mHits++;
                            if (am.isBlocking()) {
                                return requestCode >= 0 ? am.getResult() : null;
                            }
                            break;
                        }
                    }
                }
            }
            try {

         //调用ActivityManagerProxystartActivity方法
                int result = ActivityManagerNative.getDefault()
                    .startActivity(whoThread, intent,
                            intent.resolveTypeIfNeeded(who.getContentResolver()),
                            null, 0, token, target != null ? target.mEmbeddedID : null,
                            requestCode, false, false);
                checkStartActivityResult(result, intent);
            } catch (RemoteException e) {
            }
            return null;
        }

    4. ActivityManagerProxy startActivity的具体实现:

    public int startActivity(IApplicationThread caller, Intent intent,
                String resolvedType, Uri[] grantedUriPermissions, int grantedMode,
                IBinder resultTo, String resultWho,
                int requestCode, boolean onlyIfNeeded,
                boolean debug) throws RemoteException {

         // Parcel 本质上把它当成一个Serialize就可以了,只是它是在内存中完成的序列化和反序列化,利用的是连续的内存空间
            Parcel data = Parcel.obtain();
            Parcel reply = Parcel.obtain();
            data.writeInterfaceToken(IActivityManager.descriptor);
            data.writeStrongBinder(caller != null ? caller.asBinder() : null);
            intent.writeToParcel(data, 0);
            data.writeString(resolvedType);
            data.writeTypedArray(grantedUriPermissions, 0);
            data.writeInt(grantedMode);
            data.writeStrongBinder(resultTo);
            data.writeString(resultWho);
            data.writeInt(requestCode);
            data.writeInt(onlyIfNeeded ? 1 : 0);
            data.writeInt(debug ? 1 : 0);

    //具体请参照后面的代码
            mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
            reply.readException();
            int result = reply.readInt();
            reply.recycle();
            data.recycle();
            return result;
        }

    //清除sOwnedPoolparcel对象,返回一个新的parcel

    public static Parcel obtain() {

            final Parcel[] pool = sOwnedPool;

            synchronized (pool) {

                Parcel p;

                for (int i=0; i<POOL_SIZE; i++) {

                    p = pool[i];

                    if (p != null) {

                        pool[i] = null;

                        if (DEBUG_RECYCLE) {

                            p.mStack = new RuntimeException();

                        }

                        return p;

                    }

                }

            }

            return new Parcel(0);

    }

     

    // 清除pool中存储parcel,通过jni free刚才分配的内存 

      public final void recycle() {

            if (DEBUG_RECYCLE) mStack = null;

            freeBuffer();

            final Parcel[] pool = mOwnObject != 0 ? sOwnedPool : sHolderPool;

            synchronized (pool) {

                for (int i=0; i<POOL_SIZE; i++) {

                    if (pool[i] == null) {

                        pool[i] = this;

                        return;

                    }

                }

            }

        }

    //

    private native void freeBuffer();

     

     

    // mRemote 实际通过ActivityManagerNative.getDefault进行注册的,实际就是ActivityManagerService
    static public IActivityManager getDefault()

        {

            if (gDefault != null) {

                //if (Config.LOGV) Log.v(

                //    "ActivityManager", "returning cur default = " + gDefault);

                return gDefault;

            }

            IBinder b = ServiceManager.getService("activity");

            if (Config.LOGV) Log.v(

                "ActivityManager", "default service binder = " + b);

            gDefault = asInterface(b);

            if (Config.LOGV) Log.v(

                "ActivityManager", "default service = " + gDefault);

            return gDefault;

    }

    5. 实际调用proxy中的Ontransact方法

       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();

                Uri[] grantedUriPermissions = data.createTypedArray(Uri.CREATOR);

                int grantedMode = data.readInt();

                IBinder resultTo = data.readStrongBinder();

                String resultWho = data.readString();   

                int requestCode = data.readInt();

                boolean onlyIfNeeded = data.readInt() != 0;

                boolean debug = data.readInt() != 0;

                int result = startActivity(app, intent, resolvedType,

                        grantedUriPermissions, grantedMode, resultTo, resultWho,

                        requestCode, onlyIfNeeded, debug);

                reply.writeNoException();

                reply.writeInt(result);

                return true;

            }

    6 . startActivity 实际调用ActivityManagerService中的startActivity方法

    由于StartActivity太长,拿关键部分分享

    synchronized(this) {

                final long origId = Binder.clearCallingIdentity();

                int res = startActivityLocked(caller, intent, resolvedType,

                        grantedUriPermissions, grantedMode, aInfo,

                        resultTo, resultWho, requestCode, -1, -1,

                        onlyIfNeeded, componentSpecified);

                Binder.restoreCallingIdentity(origId);

                return res;

            }

    7. startActivityLocked实际调用ApplicationThreadscheduleLaunchActivity

    public final void scheduleLaunchActivity(Intent intent, IBinder token,

                    ActivityInfo info, Bundle state, List<ResultInfo> pendingResults,

                    List<Intent> pendingNewIntents, boolean notResumed, boolean isForward) {

                ActivityRecord r = new ActivityRecord();

     

                r.token = token;

                r.intent = intent;

                r.activityInfo = info;

                r.state = state;

     

                r.pendingResults = pendingResults;

                r.pendingIntents = pendingNewIntents;

     

                r.startsNotResumed = notResumed;

                r.isForward = isForward;

     

                queueOrSendMessage(H.LAUNCH_ACTIVITY, r);

            }

    8. queueOrSendMessage 然后发消息给ActivityThread Handler

      case LAUNCH_ACTIVITY: {

                        ActivityRecord r = (ActivityRecord)msg.obj;

     

                        r.packageInfo = getPackageInfoNoCheck(

                                r.activityInfo.applicationInfo);

                        handleLaunchActivity(r);

                    } break;

     

    具体调用

        private final Activity performLaunchActivity(ActivityRecord r) {

            // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

     

                    ***

                    mInstrumentation.callActivityOnCreate(activity, r.state);

                    ***

            } catch (SuperNotCalledException e) {

                throw e;

     

            } catch (Exception e) {

                if (!mInstrumentation.onException(activity, e)) {

                    throw new RuntimeException(

                        "Unable to start activity " + component

                        + ": " + e.toString(), e);

                }

            }

            return activity;

    }

     


  • 相关阅读:
    UML和序列图
    MVC超链接
    《Flink SQL任务自动生成与提交》后续:修改flink源码实现kafka connector BatchMode
    分布式条件下Integer大小比值的问题
    distribute by在spark中的一些应用
    桌面秀
    结构体sizeof的问题
    Android开发:View中调用自定义dialog出现的异常
    获取Android的源码
    【原创】VS2010中水晶报表与VS2008水晶报表版本冲突问题
  • 原文地址:https://www.cnblogs.com/budoudou/p/2100884.html
Copyright © 2020-2023  润新知