Android走進(jìn)源碼告訴你app是如何被啟動(dòng)的

前言

  • 一個(gè)app的程序是怎么啟動(dòng)的?入口在哪里?
  • 聽說ActivityManagerServices很屌,Why?
  • Activity生命周期到底是誰調(diào)用的?
  • Application又是在哪里初始化的?onCreate又是如何被調(diào)用的?
  • 面試官常常會(huì)問:為什么主線程使用looper.loop不會(huì)阻塞?
  • 等等..

是不是一直有這樣的疑問?很懵逼對(duì)不對(duì) - - ,那我們就站在巨人的丁丁上來解決一下這些問題,如果文中出現(xiàn)一些錯(cuò)誤,還望指正,互相學(xué)習(xí)


主要流程

大家都知道 Android是基于Linux系統(tǒng)的,而在Linux中,所有的進(jìn)程都是由init進(jìn)程直接或者是間接fork出來的,當(dāng)我開機(jī)的時(shí)候init進(jìn)程就會(huì)fork出一個(gè)Android的第一個(gè)新的進(jìn)程
Zygote,中文翻譯過來要”受精卵”,一個(gè)很有意識(shí)的名字。為什么這么說呢,當(dāng)我們Zygote進(jìn)程跑起來后,Android為了實(shí)現(xiàn)實(shí)現(xiàn)資源共用和更快的啟動(dòng)速度,通過Zygote進(jìn)程直接去fork出一些子進(jìn)程,這就是為什么要”受精卵”的原因,也就是我們的app全部都是基于Zygote上的 ,沒有Zygote就沒有我們,當(dāng)Zygote初始化完成之后,首先會(huì)fork它的第一個(gè)子進(jìn)程SystemServer,這個(gè)類非常的重要,為什么這么說呢?因?yàn)橄到y(tǒng)里面重要的服務(wù)都是在這個(gè)進(jìn)程里面開啟的,比如ActivityManagerService、PackageManagerServiceWindowManagerService等等,有木有覺得似曾相識(shí)
當(dāng)SystemServer跑起來后,這些重要的服務(wù)也會(huì)隨之創(chuàng)建,系統(tǒng)初始化完成之后我們就會(huì)進(jìn)到系統(tǒng)桌面->Launcher,其實(shí)Launcher也是一個(gè)app,它繼承自Activity,當(dāng)我們點(diǎn)擊桌面上的app后,系統(tǒng)就會(huì)為我們的app創(chuàng)建一個(gè)進(jìn)程,然后啟動(dòng)我們App的第一個(gè)類ActivityThread,其實(shí)說到底我們的app就是一個(gè)main函數(shù),也就是啟動(dòng)了ActivityThread.main()。我們重點(diǎn)來看下這個(gè)類

App的程序入口

都說主線程更新ui,主線程不能有耗時(shí)操作,主線程是在哪里創(chuàng)建的呢?我們來看下ActivityThread.main()。


public static void main(String[] args) {
    ....
    final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
    TrustedCertificateStore.setDefaultUserDirectory(configDir);

    Process.setArgV0("<pre-initialized>");
    //創(chuàng)建主線程Looper
    Looper.prepareMainLooper();

    ActivityThread thread = new ActivityThread();
    thread.attach(false);

    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }

    if (false) {
        Looper.myLooper().setMessageLogging(new
                LogPrinter(Log.DEBUG, "ActivityThread"));
    }

    // End of event ActivityThreadMain.
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    //主線程消息循環(huán)
    Looper.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");
}

為什么主線程使用Looper.loop()不會(huì)卡死界面

首先我們要明白一點(diǎn),主線程也是一個(gè)線程,也是有他的生命周期的,當(dāng)我們new Thread()后執(zhí)行完里面的代碼也就意味著這個(gè)線程的結(jié)束,剛說了主線程也是線程,如果我們的代碼一下就執(zhí)行完了,那么我們這個(gè)app的功能還能執(zhí)行嗎? 我還沒開始呢,你咋就結(jié)束了?這樣多不持久,Android為了解決這個(gè)問題,使用的Looper循環(huán),了解Handler的機(jī)制的童鞋,會(huì)知道在處理消息的時(shí)候使用了Looper.loop()方法,并且在該方法中進(jìn)入了一個(gè)死循環(huán)
同時(shí)Looper.loop()方法是在主線程中調(diào)用的,那么為什么沒有卡死界面呢?

線程的生命周期

首先我們要明白線程它也是有生命周期的,它的生命周期在于這個(gè)線程里面所要執(zhí)行的代碼執(zhí)行完成,這個(gè)線程的使命也就完成了

主線程如何與子線程通信

其次我們要明白我們主線程是如何跟子線程通信(發(fā)消息)的

public class MainActivity extends AppCompatActivity {
    Handler mHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new Thread(new Runnable() {
            @Override
            public void run() {
                //初始化Looper對(duì)象 一個(gè)線程對(duì)應(yīng)一個(gè)looper
                Looper.prepare();
                mHandler = new Handler() {
                    @Override
                    public void handleMessage(Message msg) {
                        super.handleMessage(msg);
                        Log.i("test", "do somethings");
                    }
                };
                //開啟消息循環(huán)
                Looper.loop();
            }

        }).start();
        findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mHandler.sendEmptyMessage(1);
            }
        });
    }

}

我們主線程跟子線程就是這樣通信的,可是為什么要 先Looper.prepare(),然后執(zhí)行處理邏輯,最后Looper.loop();
我們先來看看Looper.prepare()

public static void prepare() {
        prepare(true);
    }

    private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }

sThreadLocal你可以理解成一個(gè)hashmap鍵值對(duì),key就是我們當(dāng)前的Thread線程,value就是new Lopper出來的對(duì)象,sThreadLocal.get()如果不等于空的話 表示直接調(diào)用了prepare已經(jīng)set進(jìn)去了,就會(huì)拋出一個(gè)異常。也就是說一個(gè)線程只能對(duì)應(yīng)一個(gè)looper,人家可是很專一的~,在來看看

 /**
     * Run the message queue in this thread. Be sure to call
     * {@link #quit()} to end the loop.
     */
    public static void loop() {
        //獲取當(dāng)前線程對(duì)應(yīng)的Looper對(duì)象
        final Looper me = myLooper();
        if (me == null) {
            //沒有調(diào)用Looper.prepare()
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        }
        final MessageQueue queue = me.mQueue;

        // Make sure the identity of this thread is that of the local process,
        // and keep track of what that identity token actually is.
        Binder.clearCallingIdentity();
        final long ident = Binder.clearCallingIdentity();
        //死循環(huán),不斷從消息隊(duì)列取消息,有消息就直接處理消息
        for (;;) {
            //取出下一個(gè)消息
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                //當(dāng)前沒有消息,直接返回
                return;
            }

            // This must be in a local variable, in case a UI event sets the logger
            final Printer logging = me.mLogging;
            if (logging != null) {
                logging.println(">>>>> Dispatching to " + msg.target + " " +
                        msg.callback + ": " + msg.what);
            }

            final long traceTag = me.mTraceTag;
            if (traceTag != 0) {
                Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
            }
            try {
                //能走到這里,表示msg不為空,有消息要處理
                //調(diào)用handler.dispatchMessage()處理消息
                msg.target.dispatchMessage(msg);
            } finally {
                if (traceTag != 0) {
                    Trace.traceEnd(traceTag);
                }
            }

            if (logging != null) {
                logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
            }

            // Make sure that during the course of dispatching the
            // identity of the thread wasn't corrupted.
            final long newIdent = Binder.clearCallingIdentity();
            if (ident != newIdent) {
                Log.wtf(TAG, "Thread identity changed from 0x"
                        + Long.toHexString(ident) + " to 0x"
                        + Long.toHexString(newIdent) + " while dispatching to "
                        + msg.target.getClass().getName() + " "
                        + msg.callback + " what=" + msg.what);
            }

            msg.recycleUnchecked();
        }
    }

代碼上注釋也寫的比較清楚了,我們剛說了線程也是有生命周期的,我們?cè)诰€程里面創(chuàng)建了looper對(duì)象之后,new Handler()然后去處理消息,假如我們Looper.loop()沒有這個(gè)死循環(huán),這個(gè)線程任務(wù)就執(zhí)行完成了,那Handler里面還能收到消息嗎?所以我就需要調(diào)用Looper.loop()一個(gè)死循環(huán),不斷去消息隊(duì)列去取,然后我們主線程發(fā)了消息后,Looper取到了消息,子線程里面的Handler也就自然能夠處理消息這就是這個(gè)調(diào)用Looper.loop()的作用

主線程創(chuàng)建Handler的時(shí)候?yàn)槭裁床挥谜{(diào)用Looper.prepare(),Loop.loop()?

我們?cè)趤砜纯碅civityThread源碼

ActivityThread.java

public static void main(String[] args) {
        ...
        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Looper.loop();
        ...
}

看到木有,在我們app啟動(dòng)的時(shí)候,ActivityThread已經(jīng)幫我們做好了Looper消息循環(huán),所以我們?cè)谥骶€程new Handler()的時(shí)候就不用創(chuàng)建Looper,反而你再次調(diào)用Looper.prepare()還會(huì)報(bào)錯(cuò),因?yàn)橹骶€程已經(jīng)創(chuàng)建了Looper對(duì)象了。

為什么主線程不會(huì)卡死界面

理解了上面幾個(gè)問題我們就比較好理解了,首先,主線程也是線程,只不過這個(gè)線程是被系統(tǒng)創(chuàng)建的(就好比我們自己創(chuàng)建了子線程一樣),其次 Looper是不斷的去消息隊(duì)列里面取,取到消息就去處理消息,只要處理消息的操作不是耗時(shí)操作,就不會(huì)引起卡頓,其實(shí)Android的交互都是基于消息機(jī)制的分發(fā),handler 可以發(fā)送消息,然后loop 里就分發(fā)消息然后就發(fā)給handler, 然后就執(zhí)行到 H(Handler )里的對(duì)應(yīng)代碼。所以這些代碼就不會(huì)卡死~,也就說循環(huán)消息并不會(huì)使起卡死,而真正會(huì)卡死的是我們的處理消息,這也就是我們主線程為什么不能執(zhí)行耗時(shí)操作的原因。

舉個(gè)栗子

講到這里你可能還不是很能理解,那我們就來舉一個(gè)栗子~

我們?nèi)プ龅罔F或者做火車的時(shí)候都要去過安檢,這個(gè)安檢的機(jī)器就好比我們的Looper對(duì)象,機(jī)器內(nèi)部檢測(cè)違禁品就好比是Handler,因?yàn)槲覀円来闻抨?duì)去放到機(jī)器上去檢查,我們一個(gè)人的行李物品就比作一個(gè)Message,多個(gè)人所以就組成了一個(gè)MessageQueue, 好,有了這些東西我們就可以腦補(bǔ)整個(gè)運(yùn)行過程了,首先如果要運(yùn)行機(jī)器首先你的插插頭吧?不然怎么通電->(Looper.prepare),通完點(diǎn)后你得按開關(guān)吧?(Looper.loop),因?yàn)檫\(yùn)行很早,這個(gè)時(shí)候還沒有人來安檢,此時(shí)消息隊(duì)列(MessageQueue)是空的,這個(gè)時(shí)候我過來安檢,因?yàn)槲沂浅鋈ネ妫詭У臇|西比較少,這個(gè)時(shí)候我把我的包包(Message)放到了安檢機(jī)器的韌帶(MessageQueue)上面了,此時(shí)MessageQueue消息隊(duì)列里面就有我的包包了,機(jī)器此時(shí)正在運(yùn)轉(zhuǎn),
然后機(jī)器自動(dòng)檢測(cè)我的是否有違禁品(Handler.handleMessage),這個(gè)時(shí)候來了位大叔,帶著很大一包東西(Message),放到了MessageQueue里,這個(gè)安檢機(jī)器還在循環(huán)(Looper),當(dāng)循環(huán)到這個(gè)大叔的大件后,大叔在另一頭等待了好久發(fā)現(xiàn)怎么都不出來,因?yàn)樘?,檢測(cè)需要時(shí)間(假設(shè)機(jī)器比較low),而這個(gè)等待的時(shí)間就是我們所說的做了耗時(shí)操作導(dǎo)致ui卡頓。如果等了很久會(huì)導(dǎo)致很多乘客不滿(ANR)。這個(gè)比喻可能不是很形象,但是話粗理不粗,這個(gè)只是我的個(gè)人理解

如果大家還是不能理解的話,可以參考Android事件機(jī)制詳細(xì)解讀里面有更深入的解讀

ActivityThread.attach()

回歸上一個(gè)話題,執(zhí)行main函數(shù)的時(shí)候new ActivityThread(),執(zhí)行了它的attach方法,我們來看下attach方法

private void attach(boolean system) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
       ...
                                                
       final IActivityManager mgr =ActivityManagerNative.getDefault();
        try {
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
        // Watch for getting close to heap limit.
        BinderInternal.addGcWatcher(new Runnable() {
            @Override public void run() {
                if (!mSomeActivitiesChanged) {
                    return;
                }
                Runtime runtime = Runtime.getRuntime();
                long dalvikMax = runtime.maxMemory();
                long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
                if (dalvikUsed > ((3*dalvikMax)/4)) {
                    if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
                            + " total=" + (runtime.totalMemory()/1024)
                            + " used=" + (dalvikUsed/1024));
                    mSomeActivitiesChanged = false;
                    try {
                        mgr.releaseSomeActivities(mAppThread);
                    } catch (RemoteException e) {
                        throw e.rethrowFromSystemServer();
                    }
                }
            }
        });
    } else {
        // Don't set application object here -- if the system crashes,
        // we can't display an alert, we just want to die die die.
        android.ddm.DdmHandleAppName.setAppName("system_process",
                UserHandle.myUserId());
        try {
            mInstrumentation = new Instrumentation();
            ContextImpl context = ContextImpl.createAppContext(
                    this, getSystemContext().mPackageInfo);
            mInitialApplication = context.mPackageInfo.makeApplication(true, null);
            mInitialApplication.onCreate();
        } catch (Exception e) {
            throw new RuntimeException(
                    "Unable to instantiate Application():" + e.toString(), e);
        }
    }
}

首先attach方法有一個(gè)boolean的變量system,傳過來的是false,聰明的你一看就是這個(gè)意思,是否是系統(tǒng)應(yīng)用 ,當(dāng)然我們不是,然后我們會(huì)走到if里面,里面有一行比較關(guān)鍵的代碼

final IActivityManager mgr = ActivityManagerNative.getDefault();

我點(diǎn)進(jìn)去看下getDefault()函數(shù)

ActivityManagerNative.java

/**
 * Retrieve the system's default/global activity manager.
 */
static public IActivityManager getDefault() {
    return gDefault.get();
}

看注釋說返回一個(gè)系統(tǒng)全局的ActivityManager,調(diào)用了gDefault.get(),我們來看下這個(gè)gDefault變量看看是在哪里初始化的

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
    protected IActivityManager create() {
        IBinder b = ServiceManager.getService("activity");
        if (false) {
            Log.v("ActivityManager", "default service binder = " + b);
        }
        IActivityManager am = asInterface(b);
        if (false) {
            Log.v("ActivityManager", "default service = " + am);
        }
        return am;
    }
};

ServiceManager.getService("activity")返回一個(gè)IBinder 這個(gè)Binder對(duì)象是誰呢?既然有g(shù)etService,那么肯定有addService,并且這個(gè)key是“activity”,我們來看下是在哪個(gè)類添加的

ActivityManagerService.java


public void setSystemProcess() {
    try {
        ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
        ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
        ServiceManager.addService("meminfo", new MemBinder(this));
        ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
        ServiceManager.addService("dbinfo", new DbBinder(this));
        if (MONITOR_CPU_USAGE) {
            ServiceManager.addService("cpuinfo", new CpuBinder(this));
        }
        ServiceManager.addService("permission", new PermissionController(this));
        ServiceManager.addService("processinfo", new ProcessInfoService(this));

        ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
                "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
        mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());

        synchronized (this) {
            ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
            app.persistent = true;
            app.pid = MY_PID;
            app.maxAdj = ProcessList.SYSTEM_ADJ;
            app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
            synchronized (mPidsSelfLocked) {
                mPidsSelfLocked.put(app.pid, app);
            }
            updateLruProcessLocked(app, false, null);
            updateOomAdjLocked();
        }
    } catch (PackageManager.NameNotFoundException e) {
        throw new RuntimeException(
                "Unable to find android system package", e);
    }
}

我們看這一行代碼

ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);

看下這個(gè)Context這個(gè)常量:

public static final String ACTIVITY_SERVICE = "activity";

正好是剛才ServiceManager.getService()傳過去的key, addService()的時(shí)候傳過去一個(gè)this,也就是ActivityManagerService自己,那么getService()的時(shí)候返回的毫無疑問就是ActivityManagerService

我們?cè)诨貋砜聪翧ctivityThread.attach()方法

ActivityThread.java

final IActivityManager mgr = ActivityManagerNative.getDefault();
        try {
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }

我們搞清楚調(diào)用ActivityManagerNative.getDefault()返回了IActivityManager類型的mgr,也就是ActivityManagerService之后 ,它調(diào)用了attachApplication,并傳入了一個(gè)mAppThread我們首先來看下這個(gè)變量是什么類型

final ApplicationThread mAppThread = new ApplicationThread();

ApplicationThread,我們?cè)趤砜纯凑{(diào)用了ActivityManagerService.attachApplication做了什么事情

ActivityManagerService.java


@Override
public final void attachApplication(IApplicationThread thread) {
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid);
        Binder.restoreCallingIdentity(origId);
    }
}

調(diào)用了attachApplicationLocked(),繼續(xù)看下做了啥

這個(gè)方法比較長(zhǎng),我就只取關(guān)鍵的部分貼出來


private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid) {
....

try {
    ...    
    ProfilerInfo profilerInfo = profileFile == null ? null
            : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
    thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
            profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
            app.instrumentationUiAutomationConnection, testMode,
            mBinderTransactionTrackingEnabled, enableTrackAllocation,
            isRestrictedBackupMode || !normalMode, app.persistent,
            new Configuration(mConfiguration), app.compat,
            getCommonServicesLocked(app.isolated),
            mCoreSettingsObserver.getCoreSettingsLocked());
    updateLruProcessLocked(app, false, null);
    app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
} catch (Exception e) {
    // todo: Yikes!  What should we do?  For now we will try to
    // start another process, but that could easily get us in
    // an infinite loop of restarting processes...
    Slog.wtf(TAG, "Exception thrown during bind of " + app, e);

    app.resetPackageList(mProcessStats);
    app.unlinkDeathRecipient();
    startProcessLocked(app, "bind fail", processName);
    return false;
}

....

Application是在什么時(shí)候創(chuàng)建的?onCreate()什么時(shí)候調(diào)用的?

執(zhí)行完判斷和賦值的操作后最后調(diào)用了thread.bindApplication(),剛才看到是ApplicationThread,所以我來看看ApplicationThread.bindApplication

ActivityThread.java

private class ApplicationThread extends ApplicationThreadNative {
    private static final String DB_INFO_FORMAT = "  %8s %8s %14s %14s  %s";

    private int mLastProcessState = -1;

...
public final void bindApplication(String processName, ApplicationInfo appInfo,
        List<ProviderInfo> providers, ComponentName instrumentationName,
        ProfilerInfo profilerInfo, Bundle instrumentationArgs,
        IInstrumentationWatcher instrumentationWatcher,
        IUiAutomationConnection instrumentationUiConnection, int debugMode,
        boolean enableBinderTracking, boolean trackAllocation,
        boolean isRestrictedBackupMode, boolean persistent, Configuration config,
        CompatibilityInfo compatInfo, Map<String, IBinder> services, Bundle coreSettings) {

    if (services != null) {
        // Setup the service cache in the ServiceManager
        ServiceManager.initServiceCache(services);
    }

    setCoreSettings(coreSettings);

    AppBindData data = new AppBindData();
    data.processName = processName;
    data.appInfo = appInfo;
    data.providers = providers;
    data.instrumentationName = instrumentationName;
    data.instrumentationArgs = instrumentationArgs;
    data.instrumentationWatcher = instrumentationWatcher;
    data.instrumentationUiAutomationConnection = instrumentationUiConnection;
    data.debugMode = debugMode;
    data.enableBinderTracking = enableBinderTracking;
    data.trackAllocation = trackAllocation;
    data.restrictedBackupMode = isRestrictedBackupMode;
    data.persistent = persistent;
    data.config = config;
    data.compatInfo = compatInfo;
    data.initProfilerInfo = profilerInfo;
    sendMessage(H.BIND_APPLICATION, data);

    ...
}

可以看到是ActivityThread內(nèi)部類,我去!你在玩我呢?繞了這么半天又繞回來了。

xq

客官別急,我們繼續(xù)向下看,執(zhí)行bindApplication的時(shí)候發(fā)了一個(gè)消息

sendMessage(H.BIND_APPLICATION, data);

這個(gè)H就是我們前面說的Handler,我們來看下handler做了哪些處理

private class H extends Handler {
.....
public void handleMessage(Message msg) {
    if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
    switch (msg.what) {
        case BIND_APPLICATION:
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
        AppBindData data = (AppBindData)msg.obj;
        handleBindApplication(data);
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        break;
}

看到它調(diào)用了handleBindApplication(),其主要作用是綁定我的的自定義的application,做一些初始化操作,我們繼續(xù)看


private void handleBindApplication(AppBindData data) {
   ...

    if (ii != null) {
        final ApplicationInfo instrApp = new ApplicationInfo();
        ii.copyTo(instrApp);
        instrApp.initForUser(UserHandle.myUserId());
        final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                appContext.getClassLoader(), false, true, false);
        final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
    
        try {
            final ClassLoader cl = instrContext.getClassLoader();
            mInstrumentation = (Instrumentation)
                cl.loadClass(data.instrumentationName.getClassName()).newInstance();
        } catch (Exception e) {
            throw new RuntimeException(
                "Unable to instantiate instrumentation "
                + data.instrumentationName + ": " + e.toString(), e);
        }
    
        final ComponentName component = new ComponentName(ii.packageName, ii.name);
        mInstrumentation.init(this, instrContext, appContext, component,
                data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
    
        if (mProfiler.profileFile != null && !ii.handleProfiling
                && mProfiler.profileFd == null) {
            mProfiler.handlingProfiling = true;
            final File file = new File(mProfiler.profileFile);
            file.getParentFile().mkdirs();
            Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
        }
    } else {
        mInstrumentation = new Instrumentation();
    }
 ....

    try {
        // If the app is being launched for full backup or restore, bring it up in
        // a restricted environment with the base application class.
        Application app = data.info.makeApplication(data.restrictedBackupMode, null);
        mInitialApplication = app;
    
        // don't bring up providers in restricted mode; they may depend on the
        // app's custom Application class
        if (!data.restrictedBackupMode) {
            if (!ArrayUtils.isEmpty(data.providers)) {
                installContentProviders(app, data.providers);
                // For process that contains content providers, we want to
                // ensure that the JIT is enabled "at some point".
                mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
            }
        }
    
        // Do this after providers, since instrumentation tests generally start their
        // test thread at this point, and we don't want that racing.
        try {
            mInstrumentation.onCreate(data.instrumentationArgs);
        }
        catch (Exception e) {
            throw new RuntimeException(
                "Exception thrown in onCreate() of "
                + data.instrumentationName + ": " + e.toString(), e);
        }
    
        try {
            mInstrumentation.callApplicationOnCreate(app);
        } catch (Exception e) {
            if (!mInstrumentation.onException(app, e)) {
                throw new RuntimeException(
                    "Unable to create application " + app.getClass().getName()
                    + ": " + e.toString(), e);
            }
        }
        } finally {
            StrictMode.setThreadPolicy(savedPolicy);
        }
}

這里有個(gè)比較重要的類,mInstrumentation 為什么說它特別重要呢,我們先來看看它怎么初始化的

final ClassLoader cl = instrContext.getClassLoader();
mInstrumentation=(Instrumentation)cl.loadClass(data.instrumentationName.getClassName()).newInstance();

通過反射創(chuàng)建mInstrumentation 然后給進(jìn)行一系列初始化操作,然后執(zhí)行了

Application app = data.info.makeApplication(data.restrictedBackupMode, null);

data.info是一個(gè)LoadeApk對(duì)象。

LoadeApk.java

public Application makeApplication(boolean forceDefaultAppClass,
        Instrumentation instrumentation) {
    if (mApplication != null) {
        return mApplication;
    }

    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");

    Application app = null;

    String appClass = mApplicationInfo.className;
    if (forceDefaultAppClass || (appClass == null)) {
        appClass = "android.app.Application";
    }

    try {
        java.lang.ClassLoader cl = getClassLoader();
        if (!mPackageName.equals("android")) {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                    "initializeJavaContextClassLoader");
            initializeJavaContextClassLoader();
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
        ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
        app = mActivityThread.mInstrumentation.newApplication(
                cl, appClass, appContext);
        appContext.setOuterContext(app);
    } catch (Exception e) {
        if (!mActivityThread.mInstrumentation.onException(app, e)) {
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            throw new RuntimeException(
                "Unable to instantiate application " + appClass
                + ": " + e.toString(), e);
        }
    }
    mActivityThread.mAllApplications.add(app);
    mApplication = app;

    if (instrumentation != null) {
        try {
       //這里不會(huì)執(zhí)行,以為傳過來的是null,onCreate在上一層執(zhí)行的
            instrumentation.callApplicationOnCreate(app);
        } catch (Exception e) {
            if (!instrumentation.onException(app, e)) {
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                throw new RuntimeException(
                    "Unable to create application " + app.getClass().getName()
                    + ": " + e.toString(), e);
            }
        }
    }
}

執(zhí)行了

app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);

Instrumentation.java

static public Application newApplication(Class<?> clazz, Context context)
        throws InstantiationException, IllegalAccessException, 
        ClassNotFoundException {
    Application app = (Application)clazz.newInstance();
    app.attach(context);
    return app;
}

同樣通過反射出一個(gè)application并且 調(diào)用其attach(),也就是說我的自定義application的時(shí)候attach就是在這里調(diào)用的

接著上面ActivityThread.handleBindApplication()中,首先反射出mInstrumentation
和Application然后執(zhí)行了下面一句代碼


try {
    mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
    if (!mInstrumentation.onException(app, e)) {
        throw new RuntimeException(
            "Unable to create application " + app.getClass().getName()
            + ": " + e.toString(), e);
    }
}

調(diào)用了mInstrumentation.callApplicationOnCreate(),我們的Application.oncreate()就是在這里調(diào)用的,現(xiàn)在明白為什么Instrumentation為什么那么重要了吧,它就像個(gè)管家婆一樣,負(fù)責(zé)家里的大事小事,但是一般不拋頭露面,聽一家之主ActivityThread的安排。
好,搞清楚Application后我們?cè)趤砜纯碼ctivity在哪里被初始化以及調(diào)用oncreate()方法的

Activity是怎樣啟動(dòng)的

前面說了ActivityThread.attach()調(diào)用了ActivityManagerService.attachApplication(),在代碼中看到通過調(diào)用ApplicationThread.bindApplication()綁定了application,我們?cè)诳纯碽indApplication()之后在干了什么

ActivityManagerService.java

private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid) {
    ...
    try {
    ...
    thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
            profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
            app.instrumentationUiAutomationConnection, testMode,
            mBinderTransactionTrackingEnabled, enableTrackAllocation,
            isRestrictedBackupMode || !normalMode, app.persistent,
            new Configuration(mConfiguration), app.compat,
            getCommonServicesLocked(app.isolated),
            mCoreSettingsObserver.getCoreSettingsLocked());
    ...
    }catch (Exception e) {
    ...
    }
    ...
    if (normalMode) {
        try {
            if (mStackSupervisor.attachApplicationLocked(app)) {
                didSomething = true;
            }
        } catch (Exception e) {
            Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
            badApp = true;
        }
}

調(diào)用了mStackSupervisor.attachApplicationLocked(app),mStackSupervisor是ActivityStackSupervisor類型,這個(gè)類也是非常重要的,它決定著我們app是否能啟動(dòng)成功,我們看看做了什么

ActivityStackSupervisor.java


boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
    final String processName = app.processName;
    boolean didSomething = false;
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
    //當(dāng)前應(yīng)用的整個(gè)activity堆信息
        ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = stacks.get(stackNdx);
            if (!isFocusedStack(stack)) {
                continue;
            }
            ActivityRecord hr = stack.topRunningActivityLocked();
            if (hr != null) {
                if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                        && processName.equals(hr.processName)) {
                    try {
//啟動(dòng)Activity                        
if (realStartActivityLocked(hr, app, true, true)) {
                            didSomething = true;
                        }
                    } catch (RemoteException e) {
                        Slog.w(TAG, "Exception in new application when starting activity "
                              + hr.intent.getComponent().flattenToShortString(), e);
                        throw e;
                    }
                }
            }
        }
    }
    if (!didSomething) {
        ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
    }
    return didSomething;
}

看到調(diào)用了realStartActivityLocked(hr, app, true, true)),繼續(xù)看


final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
        boolean andResume, boolean checkConfig) throws RemoteException {
    ...
    if (andResume) {
        app.hasShownUi = true;
        app.pendingUiClean = true;
    }
    app.forceProcessStateUpTo(mService.mTopProcessState);
    app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
            System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
            new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
            task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
            newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
    ...
}

看到了調(diào)用了app.thread.scheduleLaunchActivity(),這個(gè)app是上一層傳過來的ActivityRecord,它代表的就是要開啟的Activity對(duì)象里面分裝了很多信息,比如所在的ActivityTask等,如果這是首次打開應(yīng)用,那么這個(gè)Activity會(huì)被放到ActivityTask的棧頂,那么這個(gè)thread就是我們的ApplicationThread,我們回到ActivityThread
看下ApplicationThread.scheduleLaunchActivity()做了什么

ActivityThread.java

private class ApplicationThread extends ApplicationThreadNative {
    @Override
    public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
            ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
            CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
            int procState, Bundle state, PersistableBundle persistentState,
            List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
            boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
        ...
        updatePendingConfiguration(curConfig);
    
        sendMessage(H.LAUNCH_ACTIVITY, r);
    
    }
}

又用hanlder發(fā)了個(gè)消息,我們來看看hanlder怎么處理的


public void handleMessage(Message msg) {
    if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
    switch (msg.what) {
        case LAUNCH_ACTIVITY: {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
            final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
        
            r.packageInfo = getPackageInfoNoCheck(
                    r.activityInfo.applicationInfo, r.compatInfo);
            handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    } 
    break;

}

Word天,幾經(jīng)周折又回到ActivityThread自己,心好累。。我們繼續(xù)~

ActivityThread.java

    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();
        mSomeActivitiesChanged = true;

        if (r.profilerInfo != null) {
            mProfiler.setProfiler(r.profilerInfo);
            mProfiler.startProfiling();
        }

        // Make sure we are running with the most recent config.
        handleConfigurationChanged(null, null);

        if (localLOGV) Slog.v(
            TAG, "Handling launch of " + r);

        // Initialize before creating the activity
        WindowManagerGlobal.initialize();
        //反射創(chuàng)建一個(gè)Activity
        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;
            //調(diào)用Activity.onResume
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

            if (!r.activity.mFinished && r.startsNotResumed) {
                // The activity manager actually wants this one to start out paused, because it
                // needs to be visible but isn't in the foreground. We accomplish this by going
                // through the normal startup (because activities expect to go through onResume()
                // the first time they run, before their window is displayed), and then pausing it.
                // However, in this case we do -not- need to do the full pause cycle (of freezing
                // and such) because the activity manager assumes it can just retain the current
                // state it has.
                performPauseActivityIfNeeded(r, reason);

                // We need to keep around the original state, in case we need to be created again.
                // But we only do this for pre-Honeycomb apps, which always save their state when
                // pausing, so we can not have them save their state when restarting from a paused
                // state. For HC and later, we want to (and can) let the state be saved as the
                // normal part of stopping the activity.
                if (r.isPreHoneycomb()) {
                    r.state = oldState;
                }
            }
        } else {
            // If there was an error, for any reason, tell the activity manager to stop us.
            try {
                ActivityManagerNative.getDefault()
                    .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
    }

看到開頭 ,關(guān)鍵代碼調(diào)用了Activity a = performLaunchActivity(r, customIntent);
返回一個(gè)Activity,我們看看performLaunchActivity()

ActivityThread.java

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        ComponentName component = r.intent.getComponent();
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }

        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            //通過反射創(chuàng)建activity實(shí)例
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }

        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
            if (localLOGV) Slog.v(
                    TAG, r + ": app=" + app
                    + ", appName=" + app.getPackageName()
                    + ", pkg=" + r.packageInfo.getPackageName()
                    + ", comp=" + r.intent.getComponent().toShortString()
                    + ", dir=" + r.packageInfo.getAppDir());

            if (activity != null) {
                //創(chuàng)建BaseContext
                Context appContext = createBaseContextForActivity(r, activity);
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (r.overrideConfig != null) {
                    config.updateFrom(r.overrideConfig);
                }
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                        + r.activityInfo.name + " with config " + config);
                Window window = null;
                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                    window = r.mPendingRemoveWindow;
                    r.mPendingRemoveWindow = null;
                    r.mPendingRemoveWindowManager = null;
                }
                //我們的activity.attach就在這里被調(diào)用的
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                activity.mStartedActivity = false;
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }

                activity.mCalled = false;
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onCreate()");
                }
                r.activity = activity;
                r.stopped = true;
                if (!r.activity.mFinished) {
                    activity.performStart();
                    r.stopped = false;
                }
                if (!r.activity.mFinished) {
                    if (r.isPersistable()) {
                        if (r.state != null || r.persistentState != null) {
                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                    r.persistentState);
                        }
                    } else if (r.state != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                    }
                }
                if (!r.activity.mFinished) {
                    activity.mCalled = false;
                    if (r.isPersistable()) {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state,
                                r.persistentState);
                    } else {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state);
                    }
                    if (!activity.mCalled) {
                        throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                            " did not call through to super.onPostCreate()");
                    }
                }
            }
            r.paused = true;

            mActivities.put(r.token, r);

        } 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;
    }

我們看到通過調(diào)用mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);返回一個(gè)Activity,哇~這個(gè)管家婆真是厲害!看看做了啥?肯定是反射創(chuàng)建一個(gè)Activity嘛。。不信?

Instrumentation.java

public Activity newActivity(ClassLoader cl, String className,
        Intent intent)
        throws InstantiationException, IllegalAccessException,
        ClassNotFoundException {
    return (Activity)cl.loadClass(className).newInstance();
}

不得不說Instrumentation真是任勞任怨啊。。

好,接著上面創(chuàng)建Activity之后,判斷activity是否不等于空,走進(jìn)if里面調(diào)用了

activity.attach(appContext, this, getInstrumentation(), r.token,
        r.ident, app, r.intent, r.activityInfo, title, r.parent,
        r.embeddedID, r.lastNonConfigurationInstances, config,
        r.referrer, r.voiceInteractor, window);

原來我們Activity的attach在這里調(diào)用的啊。。。接著下面走

if (r.isPersistable()) {
    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
    mInstrumentation.callActivityOnCreate(activity, r.state);
}

看到?jīng)]!看到?jīng)]!熟悉不,我的application.onCreate也是這樣調(diào)用的,管家婆666666

Instrumentation.java

public void callActivityOnCreate(Activity activity, Bundle icicle) {
    prePerformCreate(activity);
    activity.performCreate(icicle);
    postPerformCreate(activity);
}

調(diào)用了activity.performCreate(icicle);看到這么名字就應(yīng)該很清楚了吧~,又不信?

Activity.java

final void performCreate(Bundle icicle) {
    restoreHasCurrentPermissionRequest(icicle);
    onCreate(icicle);
    mActivityTransitionState.readState(icicle);
    performCreateCommon();
}

看到木有~~~回到上面,當(dāng)執(zhí)行handleLaunchActivity的時(shí)候,調(diào)用performLaunchActivity(r, customIntent);返回了Activity之后
我們接著向下看

ActivityThread.java

Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
    r.createdConfig = new Configuration(mConfiguration);
    reportSizeConfigurations(r);
    Bundle oldState = r.state;
    handleResumeActivity(r.token, false, r.isForward,
            !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
}

調(diào)用了handleResumeActivity,不用說 我敢肯定是用mInstrumentation來調(diào)用Activity.onResume的,我們來驗(yàn)證一下

final void handleResumeActivity(IBinder token,
        boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
    ActivityClientRecord r = mActivities.get(token);
    
    ....    
    // TODO Push resumeArgs into the activity for consideration
    r = performResumeActivity(token, clearHide, reason);
    ....
}

繼續(xù)看performResumeActivity()

public final ActivityClientRecord performResumeActivity(IBinder token,
        boolean clearHide, String reason) {
ActivityClientRecord r = mActivities.get(token);
if (localLOGV) Slog.v(TAG, "Performing resume of " + r
        + " finished=" + r.activity.mFinished);
if (r != null && !r.activity.mFinished) {
    if (clearHide) {
        r.hideForNow = false;
        r.activity.mStartedActivity = false;
    }
    try {
        r.activity.onStateNotSaved();
        r.activity.mFragments.noteStateNotSaved();
        if (r.pendingIntents != null) {
            deliverNewIntents(r, r.pendingIntents);
            r.pendingIntents = null;
        }
        if (r.pendingResults != null) {
            deliverResults(r, r.pendingResults);
            r.pendingResults = null;
        }
        r.activity.performResume();
...
} catch (Exception e) {
    if (!mInstrumentation.onException(r.activity, e)) {
        throw new RuntimeException(
            "Unable to resume activity "
            + r.intent.getComponent().toShortString()
            + ": " + e.toString(), e);
    }
}
}

看到了調(diào)用r.activity.performResume(),我們?cè)诶^續(xù)看看Activity.performResume()

Activity.java

final void performResume() {
    performRestart();

    mFragments.execPendingActions();

    mLastNonConfigurationInstances = null;

    mCalled = false;
    // mResumed is set by the instrumentation
    mInstrumentation.callActivityOnResume(this);
    if (!mCalled) {
        throw new SuperNotCalledException(
            "Activity " + mComponent.toShortString() +
            " did not call through to super.onResume()");
    }

    // invisible activities must be finished before onResume() completes
    if (!mVisibleFromClient && !mFinished) {
        Log.w(TAG, "An activity without a UI must call finish() before onResume() completes");
        if (getApplicationInfo().targetSdkVersion
                > android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
            throw new IllegalStateException(
                    "Activity " + mComponent.toShortString() +
                    " did not call finish() prior to onResume() completing");
        }
    }

    // Now really resume, and install the current status bar and menu.
    mCalled = false;

    mFragments.dispatchResume();
    mFragments.execPendingActions();

    onPostResume();
    if (!mCalled) {
        throw new SuperNotCalledException(
            "Activity " + mComponent.toShortString() +
            " did not call through to super.onPostResume()");
    }
}

調(diào)用了mInstrumentation.callActivityOnResume(this);看來我們的驗(yàn)證是沒錯(cuò)的

結(jié)語

至此,Activity整個(gè)的啟動(dòng)流程也講完了,大家也看到,調(diào)用過程極其復(fù)雜
源碼中各種條件判斷讓人眼花繚亂,所以說如果你沒記住也沒關(guān)系,你只要記住這個(gè)流程,理解了Android在控制Activity生命周期時(shí)是如何操作,以及是通過哪幾個(gè)關(guān)鍵的類進(jìn)行操作的就可以了,以后遇到相關(guān)的問題之道從哪塊下手即可,這些過程我雖然也是擼了一遍,但還是記不清。

時(shí)序圖

為了大家方便,我整理了下整個(gè)的調(diào)用過程

點(diǎn)我查看高清無碼大圖

以上是本文講的整個(gè)流程圖,寫的比較水,希望對(duì)大家學(xué)習(xí)有所幫助。。。

Android Studio查看源碼的小技巧

不知道大家遇到過沒,我們平時(shí)做項(xiàng)目的時(shí)候,想要查看哪些類使用了這個(gè)變量的,或者調(diào)用過這個(gè)類的方法的時(shí)候,都會(huì)去按住Ctrl加上鼠標(biāo)點(diǎn)擊那個(gè)變量或者方法,但是你只能查看自己的項(xiàng)目使用過
比如你想查看這個(gè)方法在哪里使用過你可以按住ctrl再點(diǎn)擊這個(gè)方法查看它的引用


可是我們查看源碼的時(shí)候,比如我們查看ActivityThread的源碼 想看一下handleResumeActivity在哪里調(diào)用了,可是你會(huì)發(fā)現(xiàn)你按住ctrl在點(diǎn)擊會(huì)找不到引用。為什么呢?因?yàn)槟J(rèn)是搜索你的項(xiàng)目,也就是說只要你的項(xiàng)目調(diào)用了這個(gè)方法,你才可以搜到,可是這是系統(tǒng)調(diào)用的,我想查看到底是誰調(diào)用的,怎么辦捏?

右鍵單擊這個(gè)方法彈出菜單,點(diǎn)擊Find Usages,快捷是Ctrl+g

默認(rèn)是搜索我們的Project引用,我們修改成

然后點(diǎn)擊Find

就找了調(diào)用的地方,然后我們雙擊就到了調(diào)用的那行代碼,下次你在按住ctrl單擊那個(gè)方法的時(shí)候就會(huì)彈出來引用的地方

這對(duì)于我們查看源碼有很大的幫助~

參考

【凱子哥帶你學(xué)Framework】Activity啟動(dòng)過程全解析

Android系統(tǒng)進(jìn)程Zygote啟動(dòng)過程的源代碼分析

最后

講了那么多,對(duì)于我們這些開發(fā)者來說,看源碼是非常有必要,文中我只貼出了部分代碼,完整的代碼還要自己去看,這樣印象也會(huì)非常深刻,看一遍不會(huì),我們看兩邊,雖然一臉懵比,但是我們要相信自己,這點(diǎn)挫折怎能難倒我們程序員?最后的最后,如果文中有錯(cuò)誤的地方還望大家指出

博主整理不易,轉(zhuǎn)載請(qǐng)注明出處:
http://m.itdecent.cn/p/dde57a4eb402

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容