标签:
Intent intent=new Intent(this,TestActivity.class); startActivity(intent);
public void startActivityForResult(Intent intent, int requestCode, Bundle options) { if (mParent == null) { Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options); 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 { if (options != null) { mParent.startActivityFromChild(this, intent, requestCode, options); } else { // Note we want to go through this method for compatibility with // existing applications that may have overridden it. mParent.startActivityFromChild(this, intent, requestCode); } } }
public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { IApplicationThread whoThread = (IApplicationThread) contextThread; 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 { intent.migrateExtraStreamToClipData(); intent.prepareToLeaveProcess(); int result = ActivityManagerNative.getDefault() .startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mEmbeddedID : null, requestCode, 0, null, null, options); checkStartActivityResult(result, intent); } catch (RemoteException e) { } return null; }
static public IActivityManager More ...getDefault() { return gDefault.get(); }
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() { protected IActivityManager More ...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; } };
/*package*/ static void checkStartActivityResult(int res, Object intent) { if (res >= ActivityManager.START_SUCCESS) { return; } switch (res) { case ActivityManager.START_INTENT_NOT_RESOLVED: case ActivityManager.START_CLASS_NOT_FOUND: if (intent instanceof Intent && ((Intent)intent).getComponent() != null) throw new ActivityNotFoundException( "Unable to find explicit activity class " + ((Intent)intent).getComponent().toShortString() + "; have you declared this activity in your AndroidManifest.xml?"); throw new ActivityNotFoundException( "No Activity found to handle " + intent); case ActivityManager.START_PERMISSION_DENIED: throw new SecurityException("Not allowed to start activity " + intent); case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT: throw new AndroidRuntimeException( "FORWARD_RESULT_FLAG used while also requesting a result"); case ActivityManager.START_NOT_ACTIVITY: throw new IllegalArgumentException( "PendingIntent is not an activity"); default: throw new AndroidRuntimeException("Unknown error code " + res + " when starting " + intent); } }从上面的代码可以看出,checkStartActivityResult的作用很明显,就是检查启动Activity的结果,当无法正确启动一个Activity时,这个方法会抛出异常信息,其中最熟悉不过的就是"unable to find expliit activity class; have you declared this activity in your androidmainfest.xml"这个异常我就不说了,你懂的。
public final int More ...startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, String profileFile, ParcelFileDescriptor profileFd, Bundle options) { return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); }
public final int More ...startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { enforceNotIsolatedCaller("startActivity"); userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, true, "startActivity", null); return mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, null, null, options, userId); }
final boolean More ...resumeTopActivityLocked(ActivityRecord prev, Bundle options) { if (inResumeTopActivity) { // Don't even start recursing. return false; } boolean result = false; try { // Protect against recursion. inResumeTopActivity = true; result = resumeTopActivityInnerLocked(prev, options); } finally { inResumeTopActivity = false; } return result; }
void More ...startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { // Is this activity's application already running? ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true); r.task.stack.setLaunchTime(r); if (app != null && app.thread != null) { try { if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 || !"android".equals(r.info.packageName)) { // Don't add this if it is a platform component that is marked // to run in multiple processes, because this is actually // part of the framework so doesn't make sense to track as a // separate apk in the process. app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode, mService.mProcessStats); } realStartActivityLocked(r, app, andResume, checkConfig); return; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting activity " + r.intent.getComponent().flattenToShortString(), e); } // If a dead object exception was thrown -- fall through to // restart the application. } mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true); }
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), r.compat, r.task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
private class More ...ApplicationThread extends ApplicationThreadNative public abstract class More ...ApplicationThreadNative extends Binder implements IApplicationThread可以看出,ApplicationThread继承了ApplicationThreadNative,而ApplicationThreadNative则继承了Binder并实现了IApplicationThread接口。如果读者还记得系统的AIDL文件自动生成的代码,就会发现ApplicationThreadNative的作用其实和系统为AIDL文件生成的类是一样的。
class More ...ApplicationThreadProxy implements IApplicationThread { private final IBinder mRemote; public More ...ApplicationThreadProxy(IBinder remote) { mRemote = remote; } public final IBinder More ...asBinder() { return mRemote; } public final void More ...schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeStrongBinder(token); data.writeInt(finished ? 1 : 0); data.writeInt(userLeaving ? 1 :0); data.writeInt(configChanges); data.writeInt(dontReport ? 1 : 0); mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); } public final void More ...scheduleStopActivity(IBinder token, boolean showWindow, int configChanges) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeStrongBinder(token); data.writeInt(showWindow ? 1 : 0); data.writeInt(configChanges); mRemote.transact(SCHEDULE_STOP_ACTIVITY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); } ... }绕了一大圈,Activity的启动过程最终回到了ApplicationThread中,ApplicationThread通过scheduleLaunchActivity方法来启动Activity,代码如下:
public final void More ...scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) { updateProcessState(procState, false); ActivityClientRecord r = new ActivityClientRecord(); r.token = token; r.ident = ident; r.intent = intent; r.voiceInteractor = voiceInteractor; r.activityInfo = info; r.compatInfo = compatInfo; r.state = state; r.persistentState = persistentState; r.pendingResults = pendingResults; r.pendingIntents = pendingNewIntents; r.startsNotResumed = notResumed; r.isForward = isForward; r.profilerInfo = profilerInfo; updatePendingConfiguration(curConfig); sendMessage(H.LAUNCH_ACTIVITY, r); }
private class More ...H extends Handler { public static final int LAUNCH_ACTIVITY = 100; public static final int PAUSE_ACTIVITY = 101; public static final int PAUSE_ACTIVITY_FINISHING= 102; public static final int STOP_ACTIVITY_SHOW = 103; public static final int STOP_ACTIVITY_HIDE = 104; public static final int SHOW_WINDOW = 105; public static final int HIDE_WINDOW = 106; public static final int RESUME_ACTIVITY = 107;
public void More ...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); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; case RELAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart"); ActivityClientRecord r = (ActivityClientRecord)msg.obj; handleRelaunchActivity(r); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; case PAUSE_ACTIVITY: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2, (msg.arg1&2) != 0); maybeSnapshot(); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break;
....
}
<span style="font-family: monospace;font-size:14px; white-space: pre;"> </span><span class="kw" style="color: rgb(127, 0, 85); font-weight: bold; font-family: monospace;font-size:14px; white-space: pre;">if</span><span style="font-family: monospace;font-size:14px; white-space: pre;"> (</span><span class="mark-5#1" style="font-family: monospace;font-size:14px; white-space: pre;"><a target=_blank href="http://grepcode.com/file/repo1.maven.org/maven2/org.robolectric/android-all/5.0.0_r2-robolectric-0/android/app/ActivityThread.java#ActivityThread.0DEBUG_MESSAGES" title="boolean DEBUG_MESSAGES" class="hidden" style="padding: 0px; margin: 0px; color: rgb(0, 0, 0); text-decoration: none;">DEBUG_MESSAGES</a></span><span style="font-family: monospace;font-size:14px; white-space: pre;">) Slog.</span><a target=_blank href="http://grepcode.com/file/repo1.maven.org/maven2/org.robolectric/android-all/5.0.0_r2-robolectric-0/android/util/Slog.java#Slog.v%28java.lang.String%2Cjava.lang.String%29" title="android.util.Slog.v(java.lang.String,java.lang.String) : int" style="padding: 0px; margin: 0px; color: rgb(51, 102, 187); font-family: monospace;font-size:14px; white-space: pre;">v</a><span style="font-family: monospace;font-size:14px; white-space: pre;">(</span><span class="mark-1#1" style="font-family: monospace;font-size:14px; white-space: pre;"><a target=_blank href="http://grepcode.com/file/repo1.maven.org/maven2/org.robolectric/android-all/5.0.0_r2-robolectric-0/android/app/ActivityThread.java#ActivityThread.0TAG" title="String TAG" class="hidden" style="padding: 0px; margin: 0px; color: rgb(0, 0, 0); text-decoration: none;">TAG</a></span><span style="font-family: monospace;font-size:14px; white-space: pre;">, </span><span class="strliteral" style="color: rgb(42, 0, 255); font-family: monospace;font-size:14px; white-space: pre;">"<<< done: "</span><span style="font-family: monospace;font-size:14px; white-space: pre;"> + </span><a target=_blank href="http://grepcode.com/file/repo1.maven.org/maven2/org.robolectric/android-all/5.0.0_r2-robolectric-0/android/app/ActivityThread.java#ActivityThread.H.codeToString%28int%29" title="android.app.ActivityThread.H.codeToString(int) : String" style="padding: 0px; margin: 0px; color: rgb(51, 102, 187); font-family: monospace;font-size:14px; white-space: pre;">codeToString</a><span style="font-family: monospace;font-size:14px; white-space: pre;">(</span><span class="mark-479#1" style="font-family: monospace;font-size:14px; white-space: pre;">msg</span><span style="font-family: monospace;font-size:14px; white-space: pre;">.</span><span class="mark-480#1" style="font-family: monospace;font-size:14px; white-space: pre;">what</span><span style="font-family: monospace;font-size:14px; white-space: pre;">));</span>
<span style="font-family: monospace;font-size:14px; white-space: pre;">}</span>
private void handleLaunceActivity(ActivityClientRecord r,Iintent customIntent){ ... if(localLOGV)Slog.v(TAG,"Handling launch of"+r); Activity a=performLaunchActivity(r,customIntent); if(a!=null){ r.createdConfig=new Configuration(mConfiguration); Bundle oldState=r.statr; handleResumeActivity(r.token,false,r.isForward,!r.activity.mFinished&&!r. startsNotResumed); ... } ... }从上面的源码可以看出,perforLaunchActivity方法最终完成了Activity对象的创建和启动过程,并且ActivityThread通过handleResumeActivity方法来调用被启动Activity的onResume这以生命周期方法。
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(); 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); } }
public Activity More ...newActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException { return (Activity)cl.loadClass(className).newInstance(); }
public Application More ...makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) { if (mApplication != null) { return mApplication; } 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")) { initializeJavaContextClassLoader(); } 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)) { throw new RuntimeException( "Unable to instantiate application " + appClass + ": " + e.toString(), e); } } mActivityThread.mAllApplications.add(app); mApplication = app; if (instrumentation != null) { try { instrumentation.callApplicationOnCreate(app); } catch (Exception e) { if (!instrumentation.onException(app, e)) { throw new RuntimeException( "Unable to create application " + app.getClass().getName() + ": " + e.toString(), e); } } }
标签:
原文地址:http://blog.csdn.net/zhuxiaoxuand/article/details/51264944