android 深入activity
来源:互联网 发布:linux cp拷贝多个文件 编辑:程序博客网 时间:2024/06/05 14:10
相关类简介
一、ActivityManagerService 简称AMS,是Android内核的核心功能之一,在系统启动SystemServer时启动此服务。
AMS提供的功能主要包括以下几个方面:
1。对于Android四大组件(activity service broadcast content provider)的管理,包括启动,生命周期管理等
2.进程OOM adj以级LRU weight管理
AMS主要代码位于:frameworks\base\services\java\com\android\server\am下
二、ActivityThread 不是一个线程类,主线程调用其main方法。
main方法中关键处:
Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } AsyncTask.init(); if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } Looper.loop();
由上代码可知ActivityThread处理消息。
三、ActivityManagerNative:服务中枢,ActivityManagerNative继承自Binder并实现IActivityManager,它提供了服务接口和Binder接口的相互转化功能,并在内部存储服务代理对像,并提供了getDefault方法返回服务代理
四、ActivityManagerProxy:服务代理,由ActivityManagerProxy实现,用于与Server端提供的系统服务进行进程间通信
ApplicationThread
客户端将其传送给AMS,AMS通过它与客户端通信。在这里ApplicationThread是aidl中的服务端,AMS则成为了客户端。区别客户端服务端就在与哪方调用了asInterface方法。
ActivityClientRecord
activity状态信息记录的一个描述类
ActivityRecord
AMS记录activity的信息
Context
上下文,封装公共的操作,如获取资源
Instrumentation
负责打开activity各种生命周期方法。作用:application的创建,生命周期的管理,启动activity
由浅入深进行分析
在activity的onCreate中抛异常,可得到如下log
打开一个应用,则会启动一个应用进程,然后创建一个主线程,之后调用ActivityThread的main方法。
main方法关键代码
Looper.prepareMainLooper();//一个主线程的looper对象 ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } AsyncTask.init(); if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } Looper.loop();
thread.attach(false)中关键代码:
//ActivityManagerNative的getDefault方法,可以得到一个ActivityManagerProxy对像的引用,进而通过该代理对像调用远程服务AMS的方法,也就是说应用通过ActivityManagerProxy与AMS通信。IActivityManager mgr = ActivityManagerNative.getDefault(); try { //这里mAppThread为ApplicationThread,将启动的应用的mAppThread传附加到AMS,AMS通过获取mAppThread这个IBinder的代理与应用通信。其原理就是AIDL mgr.attachApplication(mAppThread); } catch (RemoteException ex) { // Ignore }
对于孰知AIDL的同学,肯定知道,其上attachApplication方法是被代理对象调用。查看代理对象ActivityManagerProxy的attachApplication方法,发现其关键一行mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
在AIDL中,ActivityManagerProxy为服务端ActivityManagerNative的代理对象,接着产看ActivityManagerNative的onTransact方法中有该ATTACH_APPLICATION_TRANSACTION对应的地方,代码如下:
case ATTACH_APPLICATION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IApplicationThread app = ApplicationThreadNative.asInterface( data.readStrongBinder()); if (app != null) { attachApplication(app); } reply.writeNoException(); return true; }
这里获取ApplicationThreadNative的代理对象,然后将该代理对象附加到AMS。AMS继承自ActivityManagerNative。AMS的attachApplication方法:
@Override public final void attachApplication(IApplicationThread thread) { synchronized (this) { int callingPid = Binder.getCallingPid(); final long origId = Binder.clearCallingIdentity(); attachApplicationLocked(thread, callingPid); Binder.restoreCallingIdentity(origId); } }
继续看attachApplicationLocked方法,其中有这么一行代码:
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, profileFile, profileFd, profileAutoStop, app.instrumentationArguments, app.instrumentationWatcher, app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), mCoreSettingsObserver.getCoreSettingsLocked());
thread为ApplicationThread的代理类,调用了代理类的bindApplication方法。ApplicationThread的bindApplication被调用,其实ApplicationThread继承自ApplicationThreadNative。
ApplicationThread的bindApplication方法:
public final void bindApplication(String processName, ApplicationInfo appInfo, List<ProviderInfo> providers, ComponentName instrumentationName, String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler, Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher, IUiAutomationConnection instrumentationUiConnection, int debugMode, boolean enableOpenGlTrace, 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.enableOpenGlTrace = enableOpenGlTrace; data.restrictedBackupMode = isRestrictedBackupMode; data.persistent = persistent; data.config = config; data.compatInfo = compatInfo; data.initProfileFile = profileFile; data.initProfileFd = profileFd; data.initAutoStopProfiler = false; queueOrSendMessage(H.BIND_APPLICATION, data); }
这里发了一个消息给H,再通过H处理消息,执行ActivityThread的handleBindApplication方法。
startActivity过程
startActivity启动过程分析,这篇文章分析很详细了。
我这里简单说下,有了之前的分析,我们已经知道了应用与AMS的通信过程,通过ActivityManagerNative获取AMS的代理对象,并执行代理对象的startActivity方法,ActivityManagerNative的onTransact
处理代理端发的请求,执行START_ACTIVITY_TRANSACTION这个case。中间经历一段处理过程,然后看ASS.realStartActivityLocked这个方法,ASS是ActivityStackSupervisor。其中关键一句
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
执行了ApplicationThreadProxy的scheduleLaunchActivity方法。该代理transact一个SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION,查看
ApplicationThreadNative的onTransact中的SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION的case。执行了ActivityThread的scheduleLaunchActivity方法。然后发了一个消息给H
也就是这句queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
H中相应case的地方:
case LAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); ActivityClientRecord r = (ActivityClientRecord)msg.obj; r.packageInfo = getPackageInfoNoCheck( r.activityInfo.applicationInfo, r.compatInfo); handleLaunchActivity(r, null); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break;
执行了ActivityThread的handleLaunchActivity方法。查看H中其他case,可以找到activity相应生命周期对应的消息(如PAUSE_ACTIVITY)。接着看上面,handleLaunchActivity中执行了performLaunchActivity方法,performLaunchActivity中关键代码:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { .......省略 Activity activity = null; try { java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); //通过Instrumentation.newActivity创建activity 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 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) { //createBaseContextForActivity中activity与Context相互关联 Context appContext = createBaseContextForActivity(r, 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与windowi关联 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; //生命周期onCreate调用 mInstrumentation.callActivityOnCreate(activity, r.state); ....省略 } 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; }
通过Instrumentation.newActivity创建activity,其方法:
public Activity newActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException { return (Activity)cl.loadClass(className).newInstance(); }
就是通过ClassLoader来newInstance。接着看performLaunchActivity中Application的创建:
public Application 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(); ContextImpl appContext = new ContextImpl(); appContext.init(this, null, mActivityThread); //这里创建Application app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext); appContext.setOuterContext(app); //从这代码块可看出ContextImpl与Application相互关联(Application关联ContextImpl在mInstrumentation.newApplication中可看到,其实Activity也一样的,后面会看到) } 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 { //Application生命周期调用,也就是onCreate instrumentation.callApplicationOnCreate(app); } catch (Exception e) { if (!instrumentation.onException(app, e)) { throw new RuntimeException( "Unable to create application " + app.getClass().getName() + ": " + e.toString(), e); } } } return app; }
回到performLaunchActivity方法中,看
activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config);
attach方法代码:
mWindow = PolicyManager.makeNewWindow(this);//mWindow设置按键事件回调,this是activity,底层处理完一系列物理按键时间后到应用层这边,activity的dispatch系列方法回调。如Activity的dispatchKeyEvent起到拦截按键作用,如果这一步不处理,将分发DecorView处理。 mWindow.setCallback(this); mWindow.getLayoutInflater().setPrivateFactory(this); if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) { mWindow.setSoftInputMode(info.softInputMode); } if (info.uiOptions != 0) { mWindow.setUiOptions(info.uiOptions); } mUiThread = Thread.currentThread(); mMainThread = aThread; mInstrumentation = instr; mToken = token; mIdent = ident; mApplication = application; mIntent = intent; mComponent = intent.getComponent(); mActivityInfo = info; mTitle = title; mParent = parent; mEmbeddedID = id;
mWindow = PolicyManager.makeNewWindow(this)创建了一个PhoneWindow。之后执行mInstrumentation.callActivityOnCreate(activity, r.state),activity的onCreate会执行,我们一般会写setContentView方法
public void setContentView(int layoutResID) { //window就是之前所创建 getWindow().setContentView(layoutResID); initActionBar(); }
PhoneWindow的
@Override public void setContentView(int layoutResID) { if (mContentParent == null) { //创建decoreview,生成并设置整个布局 installDecor(); } else { mContentParent.removeAllViews(); } mLayoutInflater.inflate(layoutResID, mContentParent); final Callback cb = getCallback(); if (cb != null && !isDestroyed()) { cb.onContentChanged(); } }
activity的onResume分析
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) { ...省略 //这句间接执行了activity的onResume ActivityClientRecord r = performResumeActivity(token, clearHide); ...省略 //下面windowmanager添加window,windowmanager在activity的attach方法中创建赋值的。 if (r.window == null && !a.mFinished && willBeVisible) { r.window = r.activity.getWindow(); View decor = r.window.getDecorView(); decor.setVisibility(View.INVISIBLE); ViewManager wm = a.getWindowManager(); WindowManager.LayoutParams l = r.window.getAttributes(); a.mDecor = decor; l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; l.softInputMode |= forwardBit; if (a.mVisibleFromClient) { a.mWindowAdded = true; //真实添加操作是WindowManagerImpl中的WindowManagerGlobal,而WindowManagerGlobal是使用ViewRootImpl做具体的操作 wm.addView(decor, l); } } ...省略 //界面真实可见了 if (r.activity.mVisibleFromClient) { r.activity.makeVisible(); }}
值得注意的是,窗口真实添加操作是WindowManagerImpl中的WindowManagerGlobal,而WindowManagerGlobal是使用ViewRootImpl做具体的操作。
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
mGlobal 是单例。
WindowManagerGlobal的addView方法与ViewRootImpl相关的地方:
...root = new ViewRootImpl(view.getContext(), display);...root.setView(view, wparams, panelParentView);...
ViewRootImpl的setView方法中有句view.assignParent(this),这句就是将DecorView的parent赋值为ViewRootImpl。如果调用view的
invalidate,会一层一层往上调用,最后调用ViewRootImpl的invalidateChildInParent方法。其中会执行checkThread方法,这方法会判断是否是主线程更新ui。
参考
startActivity启动过程分析
源码
- 深入剖析Android Activity
- 深入剖析Android Activity
- Android 深入Activity
- android 深入activity
- 深入理解Android Activity生命周期
- Android笔记----深入理解Activity
- Android之activity深入了解
- Android学习之Activity深入
- Android 深入分析Activity生命周期
- 深入理解 Android Activity的生命周期
- 深入理解 Android Activity的生命周期
- 深入理解 Android Activity的生命周期
- Android学习12--深入理解Activity
- android Activity和service深入介绍
- Android Activity完整的生命周期深入理解
- 深入讲解Android中Activity launchMode
- 深入讲解Android中Activity launchMode
- 深入讲解Android中Activity launchMode
- git使用以及免密码登陆
- HEARTBEAT 原理 HA (high avalable)
- iOS之报错The app's Info.plist must contain an xxx key with a string value explaining
- 从setContentView开始,了解view的加载过程
- 第一个Kotlit Android项目
- android 深入activity
- swift学习错误处理流程
- JAVA学习之路(棒棒锤)
- 欢迎使用CSDN-markdown编辑器
- Range Minimum Query and Lowest Common Ancestor 区间最值查询和最近公共祖先问题
- c++第六次实验
- postgresql最初级的、小白级的起步基础知识!
- LintCode-二叉查找树专题总结
- 实训周第四天总结