Activity源码简单解读
来源:互联网 发布:centos安装pdo 编辑:程序博客网 时间:2024/06/09 13:58
对于一个从事Android开发或者学习Android开发的人而言,最初接触到的估计还是第一个应用程序“HelloWorld”,今天我们不讲helloworld。讲讲Activity。大家也许知道,Android在大体设计上其实也是遵循Web端的MVC设计的,Activity其实就是相当于我们的View+Controller(因为我们的Activity只要是展示界面,并且一般人的做法就是将数据的处理逻辑也放在Activity中)。大部分人都知道Activity的生命周期,可能觉得Activity的启动和创建都是从它的onCreate这里开始的。其实不然,说到底启动一个java编写的应用程序,我们大部分人的思维逻辑回事这样的,它的入口函数(main方法)在哪里?我也是网上查阅资料和视屏才有这样的想法的。其实当应用程序启动的时候,也是从main作为入口进入的,只不过大部分人没有找到这个main方法在哪里了,这就是我准备要说的第一个重要的类ActivityThread(它不是一个线程类,因为它不符合我们线程的实现方式)。在Android4.0的源码里面有这样一段对ActivityThread的简单说明:
This manages the execution of the mainthread in an application process, scheduling and executing activities, broadcasts,and other operations on it as the activitymanager requests.大概意思就是说,它在一个应用程序中管理者主线程的执行,例如activity,broadcast还有一些其他的操作。
先来看看ActivityThread中的main方法:
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); Process.setArgV0("<pre-initialized>"); Looper.prepareMainLooper(); if (sMainThreadHandler == null) { sMainThreadHandler = new Handler(); } ActivityThread thread = new ActivityThread(); thread.attach(false); if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }}
函数首先初始化一个Looper对象,用于消息之间的通信,代码的16,17行初始化一个ActivityThread对象,调用thread.attach(false)方法,我们进入这个方法中查看:
private void attach(boolean system) { sThreadLocal.set(this); mSystemThread = system; if (!system) { ViewRootImpl.addFirstDrawHandler(new Runnable() { public void run() { ensureJitEnabled(); } }); android.ddm.DdmHandleAppName.setAppName("<pre-initialized>"); RuntimeInit.setApplicationObject(mAppThread.asBinder()); IActivityManager mgr = ActivityManagerNative.getDefault(); try { mgr.attachApplication(mAppThread); } catch (RemoteException ex) { // Ignore } } 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"); try { mInstrumentation = new Instrumentation(); ContextImpl context = new ContextImpl(); context.init(getSystemContext().mPackageInfo, null, this); Application app = Instrumentation.newApplication(Application.class, context); mAllApplications.add(app); mInitialApplication = app; app.onCreate(); } catch (Exception e) { throw new RuntimeException( "Unable to instantiate Application():" + e.toString(), e); } } ViewRootImpl.addConfigCallback(new ComponentCallbacks2() { public void onConfigurationChanged(Configuration newConfig) { synchronized (mPackages) { // We need to apply this change to the resources // immediately, because upon returning the view // hierarchy will be informed about it. if (applyConfigurationToResourcesLocked(newConfig, null)) { // This actually changed the resources! Tell // everyone about it. if (mPendingConfiguration == null || mPendingConfiguration.isOtherSeqNewer(newConfig)) { mPendingConfiguration = newConfig; queueOrSendMessage(H.CONFIGURATION_CHANGED, newConfig); } } } } public void onLowMemory() { } public void onTrimMemory(int level) { } }); }
代码12行初始化了一个ActivityManager对象,不过看名称就知道它是一个远程的ActivityManager对象,用来管理我们的Activity,
代码14行将我们的Applicatin对象与ActivityThread对象相关联。
代码23行初始化了一个在整个activity生命中期中处于比较重要地位的一个Instrumentation对象,它负责创建初始化Activity,Application等等,
24行初始化上下文ContextImpl(context是抽象类,只能初始化其实现类)
26行创建了Application对象(其实它的创建挺简单,就是利用反射机制,Class 对象,下文的Activity也是这样创建的,自己可以跟踪源代码查看)最后就是监听了系统的Configuration变化,并对不同的配置做出不同的消息响应。
了解完ActivityThread中的Main方法只会,我们就应该谈谈Activity的创建以及Activity的各个生命周期方法具体是怎么回调的呢?带着这些疑问继续来查看ActivityThread的源代码,发现有一个继承了Hanlder的类H ,它主要是进行系统之间的消息通信的,并联系着Activity各个生命周期函数。看看里面处理消息的handleMessage方法:
public void handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + msg.what); switch (msg.what) { case LAUNCH_ACTIVITY: { ActivityClientRecord r = (ActivityClientRecord)msg.obj; r.packageInfo = getPackageInfoNoCheck( r.activityInfo.applicationInfo, r.compatInfo); handleLaunchActivity(r, null); } break; case RELAUNCH_ACTIVITY: { ActivityClientRecord r = (ActivityClientRecord)msg.obj; handleRelaunchActivity(r); } break; case PAUSE_ACTIVITY: handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2); maybeSnapshot(); break; case PAUSE_ACTIVITY_FINISHING: handlePauseActivity((IBinder)msg.obj, true, msg.arg1 != 0, msg.arg2); break; case STOP_ACTIVITY_SHOW: handleStopActivity((IBinder)msg.obj, true, msg.arg2); break; case STOP_ACTIVITY_HIDE: handleStopActivity((IBinder)msg.obj, false, msg.arg2); break; case SHOW_WINDOW: handleWindowVisibility((IBinder)msg.obj, true); break; case HIDE_WINDOW: handleWindowVisibility((IBinder)msg.obj, false); break; case RESUME_ACTIVITY: handleResumeActivity((IBinder)msg.obj, true, msg.arg1 != 0); break; case SEND_RESULT: handleSendResult((ResultData)msg.obj); break; case DESTROY_ACTIVITY: handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0, msg.arg2, false); break; case BIND_APPLICATION: AppBindData data = (AppBindData)msg.obj; handleBindApplication(data); break; case EXIT_APPLICATION: if (mInitialApplication != null) { mInitialApplication.onTerminate(); } Looper.myLooper().quit(); break; case NEW_INTENT: handleNewIntent((NewIntentData)msg.obj); break; case RECEIVER: handleReceiver((ReceiverData)msg.obj); maybeSnapshot(); break; case CREATE_SERVICE: handleCreateService((CreateServiceData)msg.obj); break; case BIND_SERVICE: handleBindService((BindServiceData)msg.obj); break; case UNBIND_SERVICE: handleUnbindService((BindServiceData)msg.obj); break; case SERVICE_ARGS: handleServiceArgs((ServiceArgsData)msg.obj); break; case STOP_SERVICE: handleStopService((IBinder)msg.obj); maybeSnapshot(); break; case REQUEST_THUMBNAIL: handleRequestThumbnail((IBinder)msg.obj); break; case CONFIGURATION_CHANGED: handleConfigurationChanged((Configuration)msg.obj, null); break; case CLEAN_UP_CONTEXT: ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj; cci.context.performFinalCleanup(cci.who, cci.what); break; case GC_WHEN_IDLE: scheduleGcIdler(); break; case DUMP_SERVICE: handleDumpService((DumpComponentInfo)msg.obj); break; case LOW_MEMORY: handleLowMemory(); break; case ACTIVITY_CONFIGURATION_CHANGED: handleActivityConfigurationChanged((IBinder)msg.obj); break; case PROFILER_CONTROL: handleProfilerControl(msg.arg1 != 0, (ProfilerControlData)msg.obj, msg.arg2); break; case CREATE_BACKUP_AGENT: handleCreateBackupAgent((CreateBackupAgentData)msg.obj); break; case DESTROY_BACKUP_AGENT: handleDestroyBackupAgent((CreateBackupAgentData)msg.obj); break; case SUICIDE: Process.killProcess(Process.myPid()); break; case REMOVE_PROVIDER: completeRemoveProvider((IContentProvider)msg.obj); break; case ENABLE_JIT: ensureJitEnabled(); break; case DISPATCH_PACKAGE_BROADCAST: handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj); break; case SCHEDULE_CRASH: throw new RemoteServiceException((String)msg.obj); case DUMP_HEAP: handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj); break; case DUMP_ACTIVITY: handleDumpActivity((DumpComponentInfo)msg.obj); break; case SLEEPING: handleSleeping((IBinder)msg.obj, msg.arg1 != 0); break; case SET_CORE_SETTINGS: handleSetCoreSettings((Bundle) msg.obj); break; case UPDATE_PACKAGE_COMPATIBILITY_INFO: handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj); break; case TRIM_MEMORY: handleTrimMemory(msg.arg1); break; } if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + msg.what); }
在handlerMessage方法中分别对了Activity不同生命周期做了相应的处理:在第9行中中handleLaunchActivity(r,null)处理了Activity创建执行的方法,我们跟踪进入这个方法
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. unscheduleGcIdler(); if (r.profileFd != null) { mProfiler.setProfiler(r.profileFile, r.profileFd); mProfiler.startProfiling(); mProfiler.autoStopProfiler = r.autoStopProfiler; } // Make sure we are running with the most recent config. handleConfigurationChanged(null, null); 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.state; handleResumeActivity(r.token, false, r.isForward); 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. try { r.activity.mCalled = false; mInstrumentation.callActivityOnPause(r.activity); // We need to keep around the original state, in case // we need to be created again. r.state = oldState; if (!r.activity.mCalled) { throw new SuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onPause()"); } } catch (SuperNotCalledException e) { throw e; } catch (Exception e) { if (!mInstrumentation.onException(r.activity, e)) { throw new RuntimeException( "Unable to pause activity " + r.intent.getComponent().toShortString() + ": " + e.toString(), e); } } r.paused = true; } } 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); } catch (RemoteException ex) { // Ignore } } }
会在代码的17行发现调用了ActivityThread的performLaunchActivity方法创建了一个Activity对象,而在代码的19-22行之中判断了如果Activity对象不为null,就去调用performResumeActivity方法,看见方法名就应该猜测得出是回调Activity的onResume方法,那么到底是不是这样呢?我们还是进入performLaunchActivity中看看他是如何执行的,下面是performLaunchActivity的具体代码实现:
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(); activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); StrictMode.incrementExpectedActivityCount(activity.getClass()); r.intent.setExtrasClassLoader(cl); 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) { 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(mCompatConfiguration); if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity " + r.activityInfo.name + " with config " + config); activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config); 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; 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.state != null) { mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state); } } if (!r.activity.mFinished) { activity.mCalled = false; 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; }
粗略的查看代码的22-31行就是利用java的反射机制创建我们具体的Activity对象,和前面所说的Application对象的创建类似,这个Activity就是我们函数需要返回的具体的Activity对象,至此时刻我么的Activity对象已近产生。
代码的52-73行就是初始化了上下文对象,并且调用了Activity的attach方法将Activiy与Application,Instrumentation,contextImpl关联起来,接下来就是我们最重要的第74行代码mInstrumentation.callActivityOnCreate(activity,r.state),跟踪进入,探探究竟
ublic void callActivityOnCreate(Activity activity, Bundle icicle) { if (mWaitingActivities != null) { synchronized (mSync) { final int N = mWaitingActivities.size(); for (int i=0; i<N; i++) { final ActivityWaiter aw = mWaitingActivities.get(i); final Intent intent = aw.intent; if (intent.filterEquals(activity.getIntent())) { aw.activity = activity; mMessageQueue.addIdleHandler(new ActivityGoing(aw)); } } } } activity.performCreate(icicle); if (mActivityMonitors != null) { synchronized (mSync) { final int N = mActivityMonitors.size(); for (int i=0; i<N; i++) { final ActivityMonitor am = mActivityMonitors.get(i); am.match(activity, activity, activity.getIntent()); } } } }只需要看代码第16行调用了Activity本身的performCreate(icicle),并传入了Bundle对象,再跟进performCreate方法中,
final void performCreate(Bundle icicle) { onCreate(icicle); mVisibleFromClient = !mWindow.getWindowStyle().getBoolean( com.android.internal.R.styleable.Window_windowNoDisplay, false); mFragments.dispatchActivityCreated(); }
哈哈哈 ,至此终于看到了我们的Activity的onCreate(icicle)的回调方法了吧,到这里我们也将Activity的onCreate究竟怎么调用的顺序流程走了一遍,如果想要看Activity的其他生命周期方法的回调,也可以按照这样一条路线走下去,这里就不在赘述了。
直到现在写这篇文章的目的,就是由于以前一直想写文章可是根本就没有坚持,以至于好多东西看过又忘记了,后来再去看,得重新整理思路,现在开始写文章,就是将自己的理解思路记录下来,以后回顾查看的时候不至于走很多弯路。文章如有什么不好的地方,请大家多多指正,一起共同进步,谢谢。
- Activity源码简单解读
- Retrofit源码解读(一)--Retrofit简单流程
- Android6.0源码解读之Activity点击事件分发机制
- 源码解读
- spark第一个简单示例的源码解读
- 初识ThreadPoolExecutor(二)——源码简单解读
- WordPress解析系列之源码加载架构简单解读
- linux内核分析-简单的操作系统内核源码解读
- 官方解读Activity之一
- 个人解读Activity之一
- activity解读之一
- Activity使用场景解读
- activity的生命周期解读
- 源码解读之Intent解读
- [源码解读] FastClick.js源码解读
- Activity源码
- CppUnit源码解读(1)
- CppUnit源码解读(2)
- linux网卡设置配置
- 设计模式六大原则
- 用matlab将三条曲线放在一张双坐标的图上
- Weblogic修改AdminServer端口
- HTML <input> autofocus 属性
- Activity源码简单解读
- UIButton 字体颜色 粗体
- linux 变量截取
- Android控件GridView之仿支付宝钱包首页带有分割线的GridView九宫格的完美实现
- AR资料
- 华清星创客学员承载梦想嗨翻青春
- Python入门:os部分方法介绍(一)
- vs好用的调试技巧
- 页面发送请求,浏览器执行哪些操作