Home界面的啟動 -電腦資料

電腦資料 時間:2019-01-01 我要投稿
【m.clearvueentertainment.com - 電腦資料】

    繼上篇文章Launcher進程的啟動,我們繼續(xù)分析Home界面的啟動,

Home界面的啟動

。

public final class ActivityThread {	......	public static final void main(String[] args) {		SamplingProfilerIntegration.start();		Process.setArgV0(thread.attach函數(shù)如下:

private final void attach(boolean system) {        sThreadLocal.set(this);        mSystemThread = system;        if (!system) {            ......            IActivityManager mgr = ActivityManagerNative.getDefault();            try {                mgr.attachApplication(mAppThread);            } catch (RemoteException ex) {            }        } else {            ......        }		......}
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;    }
static public IActivityManager asInterface(IBinder obj)    {        if (obj == null) {            return null;        }        IActivityManager in =            (IActivityManager)obj.queryLocalInterface(descriptor);        if (in != null) {            return in;        }                return new ActivityManagerProxy(obj);    }
在ActivityThread類的成員函數(shù)attach中,調用ActivityManagerNative類的靜態(tài)成員函數(shù)getDefault來獲得ActivityMangerService的一個代理對象,代理對象的類型為ActivityMangerProxy。

   

    mgr.attachApplication(mAppThread)實際上調用的是ActivityManagerProxy的attachApplication,如下:

class ActivityManagerProxy implements IActivityManager{       public void attachApplication(IApplicationThread app) throws RemoteException    {        Parcel data = Parcel.obtain();        Parcel reply = Parcel.obtain();        data.writeInterfaceToken(IActivityManager.descriptor);        data.writeStrongBinder(app.asBinder());        mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);        reply.readException();        data.recycle();        reply.recycle();    }    ......}
其中app為:

final ApplicationThread mAppThread = new ApplicationThread();
繼承于ApplicationThreadNative,ApplicationThreadNative繼承于Binder實現(xiàn)了IApplicationThread。

    由于是同步傳輸,所以Launcher進程主線程睡眠等待。

    此時System進程Binder主線程池和子線程池都開啟了,正在等待來自Launcher進程的請求。

    System進程,接收到請求后,如上圖的Binder進程間通信的省略步驟一樣,會執(zhí)行如下代碼:

public abstract class ActivityManagerNative extends Binder implements IActivityManager{    ......    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)            throws RemoteException {        switch (code) {        case ATTACH_APPLICATION_TRANSACTION: {            data.enforceInterface(IActivityManager.descriptor);            IApplicationThread app = ApplicationThreadNative.asInterface(                    data.readStrongBinder());            if (app != null) {                attachApplication(app);            }            reply.writeNoException();            return true;        }    .......}
首先生成BinderProxy對象,里面的mObject指向代理對象,向上轉型為IBinder。

    然后生成ApplicationThreadProxy對象,里面mRemote指向BinderProxy對象。

    由于ActivityManagerService類繼承于ActivityManagerNative類,所以attachApplication,實際上執(zhí)行的是位于ActivityManagerService中的。

public final class ActivityManagerService extends ActivityManagerNative{    public final void attachApplication(IApplicationThread thread) {        synchronized (this) {            int callingPid = Binder.getCallingPid();            final long rigId = Binder.clearCallingIdentity();            attachApplicationLocked(thread, callingPid);            Binder.restoreCallingIdentity(origId);        }    }    .....}
這里將操作轉發(fā)給attachApplicationLocked函數(shù),如下:

public final class ActivityManagerService extends ActivityManagerNative		implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {	......	private final boolean attachApplicationLocked(IApplicationThread thread,			int pid) {		// Find the application record that is being attached...  either via		// the pid if we are running in multiple processes, or just pull the		// next app record if we are emulating process with anonymous threads.		ProcessRecord app;		if (pid != MY_PID && pid >= 0) {			synchronized (mPidsSelfLocked) {				app = mPidsSelfLocked.get(pid);//取回ProcessRecord對象,保存在app中,app就是用來描述新創(chuàng)建的應用程序進程的			}		} else if (mStartingProcesses.size() > 0) {			......		} else {			......		}		if (app == null) {			......			return false;		}		......		String processName = app.processName;		try {			thread.asBinder().linkToDeath(new AppDeathRecipient(				app, pid, thread), 0);		} catch (RemoteException e) {			......			return false;		}		......		app.thread = thread;//thread設置為參數(shù)thread所指向的一個ApplicationThread代理對象		......                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);//刪除ActivityMangerService所運行在的線程的消息隊列中PROC_START_TIMEOUT_MSG消息		boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);		......		boolean badApp = false;		boolean didSomething = false;		// See if the top visible activity is waiting to run in this process...		ActivityRecord hr = mMainStack.topRunningActivityLocked(null);//位于棧頂?shù)腁ctivityRecord是Home界面的ActivityRecord		if (hr != null && normalMode) {			if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid				&& processName.equals(hr.processName)) {					try {						if (mMainStack.realStartActivityLocked(hr, app, true, true)) {//最后走這里							didSomething = true;						}					} catch (Exception e) {						......					}			} else {				......			}		}		......		return true;	}	......}
在System進程的啟動流程第二部分,最后一部分,ActivityManager以這個PID為關鍵字將一個ProcessRecord對象保存在了成員變量mPidsSelfLocked中。所以首先通過參數(shù)pid將這個ProcessRecord對象取回來,并且保存在app中。

    然后對app初始化,其中最重要的是將它的成員變量thread設置為參數(shù)thread所指向的一個ApplicationThread代理對象。這樣,ActivityManagerService以后就可以通過這個ApplicationThread代理對象來和新創(chuàng)建的應用程序進程進行通信了。

    還記得在System進程的啟動流程第二部分,最后一部分,會向ActivityManagerService所運行的線程的消息隊列發(fā)送一個類型為PROC_START_TIMEOUT_MSG的消息,并且指定這個消息在PROC_START_TIMEOUT毫秒之后處理。

Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);  msg.obj = app;  mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
這里通過以下代碼來刪除ActivityMangerService所運行在的線程的消息隊列中PROC_START_TIMEOUT_MSG消息,因為新的應用程序進程已經(jīng)在規(guī)定的時間內啟動起來了。

   

mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app)
最后通過ActivityStack類的成員函數(shù)realStartActivityLocked來請求該應用程序進程啟動一個Activity。

public class ActivityStack {	......	final boolean realStartActivityLocked(ActivityRecord r,			ProcessRecord app, boolean andResume, boolean checkConfig)			throws RemoteException {				......		r.app = app;//r的成員變量app的值設置為參數(shù)app,表示它描述的Activity組件是在參數(shù)app所描述的應用程序進程中啟動的		......		int idx = app.activities.indexOf(r);		if (idx < 0) {			app.activities.add(r);//將該Activity添加到參數(shù)app所描述的應用程序進程的Activity組件列表中		}				......		try {			......			List<resultinfo>results = null;			List<intent>newIntents = null;			if (andResume) {				results = r.results;				newIntents = r.newIntents;			}				......						app.thread.scheduleLaunchActivity(new Intent(r.intent), r,				System.identityHashCode(r),				r.info, r.icicle, results, newIntents, !andResume,				mService.isNextTransitionForward());			......		} catch (RemoteException e) {			......		}		......		return true;	}	......}</intent></resultinfo>

    這里最終通過app.thread進入到ApplicationThreadProxy的scheduleLaunchActivity函數(shù)中,注意,這里的第二個參數(shù)r,是一個ActivityRecord類型的Binder對象,用來作來這個Activity的token值,

電腦資料

Home界面的啟動》(http://m.clearvueentertainment.com)。

public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,            ActivityInfo info, Bundle state, List<resultinfo>pendingResults,    		List<intent>pendingNewIntents, boolean notResumed, boolean isForward)    		throws RemoteException {        Parcel data = Parcel.obtain();        data.writeInterfaceToken(IApplicationThread.descriptor);        intent.writeToParcel(data, 0);        data.writeStrongBinder(token);        data.writeInt(ident);        info.writeToParcel(data, 0);        data.writeBundle(state);        data.writeTypedList(pendingResults);        data.writeTypedList(pendingNewIntents);        data.writeInt(notResumed ? 1 : 0);        data.writeInt(isForward ? 1 : 0);        mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,                IBinder.FLAG_ONEWAY);        data.recycle();    }</intent></resultinfo>
其Binder類圖如下:

   

    我們傳遞的數(shù)據(jù)token,是一個ActivityRecord類型的Binder對象,如下圖:

   

    1、由于是異步傳輸,System進程傳輸完數(shù)據(jù)后,又開始在線程池繼續(xù)等待了。

    2、 同時Launcher進程的主線程也該收到System進程返回的數(shù)據(jù)了,它還一直等待在如下代碼:

class ActivityManagerProxy implements IActivityManager{       public void attachApplication(IApplicationThread app) throws RemoteException    {        Parcel data = Parcel.obtain();        Parcel reply = Parcel.obtain();        data.writeInterfaceToken(IActivityManager.descriptor);        data.writeStrongBinder(app.asBinder());        mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);        reply.readException();        data.recycle();        reply.recycle();    }    ......}
2、Launcher進程的主線程被喚醒后,繼續(xù)運行,會返回到ActivityThread的main函數(shù),執(zhí)行Looper.loop(),這樣Launcher進程的主線程的消息循環(huán)機制就創(chuàng)立了。

    3、由于Launcher進程子線程池已經(jīng)建立,并且在睡眠等待,此時發(fā)送數(shù)據(jù),會喚醒Launcher進程子線程,如Binder類圖所示,開始執(zhí)行如下代碼:

public abstract class ApplicationThreadNative extends Binder        implements IApplicationThread {    ........    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)            throws RemoteException {        switch (code) {        case SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION:        {            data.enforceInterface(IApplicationThread.descriptor);            Intent intent = Intent.CREATOR.createFromParcel(data);            IBinder b = data.readStrongBinder();            int ident = data.readInt();            ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data);            Bundle state = data.readBundle();            List<resultinfo>ri = data.createTypedArrayList(ResultInfo.CREATOR);            List<intent>pi = data.createTypedArrayList(Intent.CREATOR);            boolean notResumed = data.readInt() != 0;            boolean isForward = data.readInt() != 0;            scheduleLaunchActivity(intent, b, ident, info, state, ri, pi,                    notResumed, isForward);            return true;        }        .....}</intent></resultinfo>
其中b為一個BinderProxy的Binder代理對象,指向了ActivityManagerService中與Launcher進程對應的一個AcitivityRecord對象,如上圖所示。

    由于ApplicationThread繼承于ApplicationThreadNative,所以真正執(zhí)行的是ApplicationThread里面的scheduleLaunchActivity方法。

public final class ActivityThread {	......	private final class ApplicationThread extends ApplicationThreadNative {		......		// we use token to identify this activity without having to send the		// activity itself back to the activity manager. (matters more with ipc)		public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,				ActivityInfo info, Bundle state, List<resultinfo>pendingResults,				List<intent>pendingNewIntents, boolean notResumed, boolean isForward) {			ActivityClientRecord r = new ActivityClientRecord();			r.token = token;			r.ident = ident;			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);		}		......	}	......}</intent></resultinfo>
函數(shù)首先創(chuàng)建一個ActivityClientRecord實例,并且初始化它的成員變量,然后調用ActivityThread類的queueOrSendMessage函數(shù)進一步處理。

   

public final class ActivityThread {	......	private final class ApplicationThread extends ApplicationThreadNative {		......		// if the thread hasn't started yet, we don't have the handler, so just		// save the messages until we're ready.		private final void queueOrSendMessage(int what, Object obj) {			queueOrSendMessage(what, obj, 0, 0);		}		......		private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {			synchronized (this) {				......				Message msg = Message.obtain();				msg.what = what;				msg.obj = obj;				msg.arg1 = arg1;				msg.arg2 = arg2;				mH.sendMessage(msg);			}		}		......	}	......}
由于目前是在Binder子線程池中處理的請求,所以queueOrSendMessage目前處于子線程,大家知道m(xù)H是主線程中Handler,剛剛完成了Loop.loop()進入了消息循環(huán)。

public final class ActivityThread {	......	private final class H extends Handler {		......		public void handleMessage(Message msg) {			......			switch (msg.what) {			case LAUNCH_ACTIVITY: {				ActivityClientRecord r = (ActivityClientRecord)msg.obj;				r.packageInfo = getPackageInfoNoCheck(					r.activityInfo.applicationInfo);				handleLaunchActivity(r, null);			} break;			......			}		......	}	......}
這里最后調用ActivityThread類的handleLaunchActivity函數(shù)進一步處理。

public final class ActivityThread {	......	private final void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {		......		Activity a = performLaunchActivity(r, customIntent);		if (a != null) {			r.createdConfig = new Configuration(mConfiguration);			Bundle ldState = r.state;			handleResumeActivity(r.token, false, r.isForward);			......		} else {			......		}	}	......}
這里首先調用performLaunchActivity函數(shù)來加載這個Activity類,即Home界面Activity,然后調用它的onCreate函數(shù),最后回到handleLaunchActivity函數(shù)時,再調用handleResumeActivity函數(shù)來使這個Activity進入Resumed狀態(tài),即會調用這個Activity的onResume函數(shù),這是遵循Activity的生命周期的。

public final class ActivityThread {	......	private final Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {				......		ComponentName component = r.intent.getComponent();		......		Activity activity = null;		try {			java.lang.ClassLoader cl = r.packageInfo.getClassLoader();			activity = mInstrumentation.newActivity(				cl, component.getClassName(), r.intent);			......		} catch (Exception e) {			......		}		try {			Application app = r.packageInfo.makeApplication(false, mInstrumentation);			......			if (activity != null) {				ContextImpl appContext = new ContextImpl();				appContext.init(r.packageInfo, r.token, this);				appContext.setOuterContext(activity);				CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());				Configuration config = new Configuration(mConfiguration);				......				activity.attach(appContext, this, getInstrumentation(), r.token,					r.ident, app, r.intent, r.activityInfo, title, r.parent,					r.embeddedID, r.lastNonConfigurationInstance,					r.lastNonConfigurationChildInstances, config);				.......				mInstrumentation.callActivityOnCreate(activity, r.state);				......			}			......			mActivities.put(r.token, r);		} catch (SuperNotCalledException e) {			......		} catch (Exception e) {			......		}		return activity;	}	......}
這樣,就開始執(zhí)行Home界面的onCreate。

    1、至此,Launcher進程Binder子線程池在給主線程發(fā)送消息后,又進入睡眠等待狀態(tài)。onCreate是通過消息機制,在主線程中執(zhí)行的。

    2、System進程又在線程池(主線程和子線程)繼續(xù)等待了。

    3、Zygote進程等待連接請求,創(chuàng)建新的應用程序進程。

最新文章