app( activity) 启动流程
来源:互联网 发布:oracle sql rowcount 编辑:程序博客网 时间:2024/06/05 16:58
本文主要通过app启动后,分析系统源码的方式来讲解activity启动,本文占时不讲Binder机制
ps:下次有空会学习并且写下Binder机制,况且我的glide源码还没有写完。本人水平有限,欢迎有老司机过来飙车,指教!
本文涉及以下几个源码:
- ActivityThread
- ActivityManagerNative
- ActivityManagerService
- ActivityStackSupervisor
- Instrumentation
- Activity
上面的源码可以通过:
自己的sdk找到 路径大致为:G:\developsoft\android\sdk_as\sources
或者通过系统源码下载 这篇文章的网站去下载相关的代码
ok,我们首先来回顾一下,在java中 ,我们要运行一个类,肯定会有一个主函数的入口,那么android也是一样的。
正式开车:
我们根据一个调用的时序图来深入简出的分析代码:
上图;
图片太大了,还不知道怎么截成一张整图,有经验老司机,请留意指教。
好了,我们来看 ActivityThread
这里只看关键的代码:
//主函数的入口函数 public static void main(String[] args) { SamplingProfilerIntegration.start(); // CloseGuard defaults to true and can be quite spammy. We // disable it here, but selectively enable it later (via // StrictMode) on debug builds, but using DropBox, not logs. CloseGuard.setEnabled(false); Environment.initForCurrentUser(); // Set the reporter for event logging in libcore EventLogger.setReporter(new EventLoggingReporter()); Security.addProvider(new AndroidKeyStoreProvider()); // Make sure TrustedCertificateStore looks in the right place for CA certificates final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId()); TrustedCertificateStore.setDefaultUserDirectory(configDir); Process.setArgV0("<pre-initialized>"); //初始化主线程的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")); } //Looper开始轮询 Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
看这个方法 thread.attach(false);删除其他的方法,我们只留关键的代码。
private void attach(boolean system) { //判断是否是系统应用 sCurrentActivityThread = this; mSystemThread = system; if (!system) { //非系统应用 ViewRootImpl.addFirstDrawHandler(new Runnable() { @Override public void run() { ensureJitEnabled(); } }); android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", UserHandle.myUserId()); RuntimeInit.setApplicationObject(mAppThread.asBinder()); //2、调用 ActivityManagerNative.getDefault(); final IActivityManager mgr = ActivityManagerNative.getDefault(); try { //7. mgr.attachApplication(mAppThread); mgr.attachApplication(mAppThread); } catch (RemoteException ex) { // Ignore } // 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) { } } } }); } else { //系统应用 } // add dropbox logging to libcore DropBox.setReporter(new DropBoxReporter()); ViewRootImpl.addConfigCallback(new ComponentCallbacks2() { @Override public void onConfigurationChanged(Configuration newConfig) { synchronized (mResourcesManager) { // We need to apply this change to the resources // immediately, because upon returning the view // hierarchy will be informed about it. if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) { // This actually changed the resources! Tell // everyone about it. if (mPendingConfiguration == null || mPendingConfiguration.isOtherSeqNewer(newConfig)) { mPendingConfiguration = newConfig; sendMessage(H.CONFIGURATION_CHANGED, newConfig); } } } } @Override public void onLowMemory() { } @Override public void onTrimMemory(int level) { } }); }
执行到 IActivityManager mgr = ActivityManagerNative.getDefault(); 这个方法,我们看看这个方法返回了什么?
我们来到:ActivityManagerNative
/** * Retrieve the system's default/global activity manager. */ //3、调用IActivityManager getDefault() static public IActivityManager getDefault() { return gDefault.get(); }
接着调用:
//4、 private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() { protected IActivityManager create() { //4、谁返回来的? 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; } };
这样就关联上了ActivityManagerService 我们看这句代码 IBinder b = ServiceManager.getService(“activity”); 那么我们去ActivityManagerService 是什么时候add进去的?我们继续往下看
public static void setSystemProcess() { try { ActivityManagerService m = mSelf; //5、添加进去 ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true); ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats); ServiceManager.addService("meminfo", new MemBinder(m)); ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); ServiceManager.addService("dbinfo", new DbBinder(m)); if (MONITOR_CPU_USAGE) { ServiceManager.addService("cpuinfo", new CpuBinder(m)); } ServiceManager.addService("permission", new PermissionController(m)); }
我们接着回到 ActivityThread 找到 mgr.attachApplication(mAppThread);
if (!system) { ViewRootImpl.addFirstDrawHandler(new Runnable() { @Override public void run() { ensureJitEnabled(); } }); android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", UserHandle.myUserId()); RuntimeInit.setApplicationObject(mAppThread.asBinder()); //2、调用 ActivityManagerNative.getDefault(); final IActivityManager mgr = ActivityManagerNative.getDefault(); try { //7. mgr.attachApplication(mAppThread); mgr.attachApplication(mAppThread); } catch (RemoteException ex) { // Ignore }
就是调用ActivityManagerService 里的 attachApplication(IApplicationThread thread)方法
@Override public final void attachApplication(IApplicationThread thread) { synchronized (this) { int callingPid = Binder.getCallingPid(); final long origId = Binder.clearCallingIdentity(); //我们注意这个方法 attachApplicationLocked(thread, callingPid); attachApplicationLocked(thread, callingPid); Binder.restoreCallingIdentity(origId); } }
我们来看下 attachApplicationLocked(thread, callingPid); 我只看一些关键的方法
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) { // See if the top visible activity is waiting to run in this process... if (normalMode) { try { //10\ attachApplicationLocked(app, mHeadless) if (mStackSupervisor.attachApplicationLocked(app, mHeadless)) { didSomething = true; } } catch (Exception e) { badApp = true; } } // Find any services that should be running in this process... if (!badApp) { try { didSomething |= mServices.attachApplicationLocked(app, processName); } catch (Exception e) { badApp = true; } } // Check if a next-broadcast receiver is in this process... if (!badApp && isPendingBroadcastProcessLocked(pid)) { try { didSomething |= sendPendingBroadcastsLocked(app); } catch (Exception e) { // If the app died trying to launch the receiver we declare it 'bad' badApp = true; } } return true; }
这就进入一个关键类了 ActivityStackSupervisor 我们看这个方法mStackSupervisor.attachApplicationLocked(app, mHeadless)
这里由于版本不一样,有的版本参数是2个,有的是一个,忽略这些细节,如果费用纠结这些细节的话,请一定要下载版本一直的源码,这里我就偷个懒,不下载了。
我们来看看ActivityStackSupervisor 这个类
boolean attachApplicationLocked(ProcessRecord app) throws Exception { final String processName = app.processName; boolean didSomething = false; for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = stacks.get(stackNdx); if (!isFrontStack(stack)) { continue; } ActivityRecord hr = stack.topRunningActivityLocked(null); if (hr != null) { if (hr.app == null && app.uid == hr.info.applicationInfo.uid && processName.equals(hr.processName)) { try { //看这个方法的名字就能猜到干啥的了, realStartActivityLocked() if (realStartActivityLocked(hr, app, true, true)) { didSomething = true; } } catch (Exception e) { Slog.w(TAG, "Exception in new application when starting activity " + hr.intent.getComponent().flattenToShortString(), e); throw e; } } } } }
我们来看看 ActivityStackSupervisor 里的 realStartActivityLocked()都做了啥?
//9真正的启动 final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { //执行启动的方法 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), r.compat, app.repProcState, r.icicle, results, newIntents, !andResume, mService.isNextTransitionForward(), profileFile, profileFd, profileAutoStop); if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) { // This may be a heavy-weight process! Note that the package // manager will ensure that only activity can run in the main // process of the .apk, which is the only thing that will be // considered heavy-weight. if (app.processName.equals(app.info.packageName)) { if (mService.mHeavyWeightProcess != null && mService.mHeavyWeightProcess != app) { Slog.w(TAG, "Starting new heavy weight process " + app + " when already running " + mService.mHeavyWeightProcess); } mService.mHeavyWeightProcess = app; Message msg = mService.mHandler.obtainMessage( ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG); msg.obj = r; mService.mHandler.sendMessage(msg); } } } catch (RemoteException e) { if (r.launchFailed) { // This is the second time we failed -- finish activity // and give up. Slog.e(TAG, "Second failure launching " + r.intent.getComponent().flattenToShortString() + ", giving up", e); mService.appDiedLocked(app, app.pid, app.thread); stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, "2nd-crash", false); return false; } // This is the first time we failed -- restart process and // retry. app.activities.remove(r); throw e; } return true; }
我们来看上面的这个方法 app.thread.scheduleLaunchActivity( ) app.thread又回到了ActivityThread类中,我们看看这个方法有些什么
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) { updateProcessState(procState, false); ActivityClientRecord r = new ActivityClientRecord(); //看到这里感觉熟悉了吧,发送了一个消息我们来找找看 sendMessage(H.LAUNCH_ACTIVITY, r); }
我们在handleMessage(Message msg) 中找到了 handleLaunchActivity(r, null);
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); //通过handle启动activity handleLaunchActivity(r, null); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break;
接着源码继续看 handleLaunchActivity(ActivityClientRecord r, Intent customIntent)
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. //执行启动 Activity a = performLaunchActivity(r, customIntent); } 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, false); } catch (RemoteException ex) { // Ignore } } }
我们看到 通过反射的方式 mInstrumentation.newActivity( cl, component.getClassName(), r.intent);创建了一个 Activity。 好了,到了我们今天最后的一个类,也是最重要的一个类了,希望你坚持看下去:mInstrumentation 代表的就是 Instrumentation
rivate Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")"); Activity activity = null; //反射创建一个Activity try { 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); } } return activity; }
我们来看看Instrumentation 他是如何创建一个activity的
public Activity newActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException { return (Activity)cl.loadClass(className).newInstance(); }
我们在回 ActivityThread 看看 mInstrumentation 都调用哪些方法?
mInstrumentation.callActivityOnDestroy(r.activity);
mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,r.persistentState);
mInstrumentation.callActivityOnDestroy(r.activity);
mInstrumentation.callActivityOnPause(r.activity);
mInstrumentation.callActivityOnUserLeaving(r.activity); ~~~~~~~~~~~~~~~~~~~~~~~~~等等 剩下方法 童靴你自己找下吧
我们来举例看一个 mInstrumentation.callActivityOnPause(r.activity); 里面它是怎么实现的?
我们在 Instrumentation 发现 是调用 activity.performPause();
public void callActivityOnPause(Activity activity) { activity.performPause(); }
那我们在去activity的源码一探究竟。
final void performPause() { mDoReportFullyDrawn = false; mFragments.dispatchPause(); mCalled = false; onPause(); mResumed = false; if (!mCalled && getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.GINGERBREAD) { throw new SuperNotCalledException( "Activity " + mComponent.toShortString() + " did not call through to super.onPause()"); } mResumed = false; }
果然有这个方法,并且 onPause();的生命周期方法也在里面。
不知道,你们明白了么? 欢迎老司机指教!
- app( activity) 启动流程
- Activity的启动流程(二)
- Activity的启动流程(二)
- Activity启动流程源码解析(原创)
- Activity启动流程分析(二)
- Activity启动流程笔记(一)
- Activity启动流程笔记(二)
- Activity的启动流程
- activity 启动流程分析
- Activity启动流程
- activity启动流程
- Activity的启动流程
- Activity的启动流程
- activity 启动流程分析
- Activity启动流程
- Activity 视图启动流程
- Activity的启动流程
- Activity启动流程
- JDBC链接Msql数据库
- greendao 3.0使用增删改查
- CSS:去除点击链接和按钮时出现的虚线框
- ViewPage 水平滑动加入刷新功能
- mt6735 [Audio Common] speaker播第一下触摸提示音时有时无声
- app( activity) 启动流程
- Java中Comparable和Comparator区别小结
- Spring-boot 启动时碰到的错误
- Linux 任务执行
- Android Studio3.0后依赖ButterKnife不成功的解决方法
- wrk-服务器压力测试工具的使用(一)
- log4j ----->flume
- 分布式锁那点事
- 每日一练25