【转】Android 之ActivityThead、ActivityManagerService 与activity的管理和创建
在android中,Activity是四大组件中比较重要的一个(当然其他的也比较重要),那么android中是怎样管理这些activity的?应用的进程和主线程是怎么创建的,应用的消息循环又是在什么时候创建的?在这篇文章中将详细介绍:
先来看下涉及到的类,通过以下类图对整体先有个大概的印象:

ActivityThread:
ActivityThread主要用来启动应用程序的主线程,并且管理在应用端跟用户打交道的activity。在应用端的activity信息全部被存储在ActivityThread的成员变量mActivities中。
- final HashMap<IBinder, ActivityRecord> mActivities= new HashMap<IBinder, ActivityRecord>();
也就是说,在mActivities中,记录了应用程序创建的所有activity实例记录,对应的是ActivityRecord。
ActivityThread是怎么启动应用程序的呢?ActivityThread中有一个main函数,在这个里面,将启动应用程序并建立消息循环。在之前也介绍过,系统会为主线程自动创建消息循环。
- /*** 应用程序的启动入口 . ,主线程在启动的时候系统会自动建立消息循环机制。*/public static final void main(String[] args) { SamplingProfilerIntegration.start(); Process.setArgV0("<pre-initialized>"); Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); Looper.loop(); if (Process.supportsProcesses()) { throw new RuntimeException("Main thread loop unexpectedly exited"); } thread.detach(); String name = (thread.mInitialApplication != null) ? thread.mInitialApplication.getPackageName() : "<unknown>";Slog.i(TAG, "Main thread of " + name + " is now exiting"); }
在建立消息循环之前,会通过thread.attach(false)来初始化应用程序的运行环境,并建立activityThread和ActivityManagerService之间的桥mAppThread, mAppThread是IApplicationThread的一个实例。
- android.ddm.DdmHandleAppName.setAppName("<pre-initialized>"); RuntimeInit.setApplicationObject(mAppThread.asBinder()); IActivityManager mgr = ActivityManagerNative.getDefault(); try { mgr.attachApplication(mAppThread); } catch (RemoteException ex) { }
注意:每个应用程序对应着一个ActivityThread实例,应用程序由ActivityThread.main打开消息循环。每个应用程序同时也对应着一个ApplicationThread对象。该对象是activityThread和ActivityManagerService之间的桥梁。
在attach中还做了一件事情,就是通过代理调用attachApplication,并利用binder的transact机制,在ActivityManagerService中建立了ProcessRecord信息。

之后通过该ProcessRecord就可以获得该ActivityThread中的所有ActivityRecord记录。下面会介绍。
ActivityManagerService:
在ActivityManagerService中,也有一个用来管理activity的地方:mHistory栈,这个mHistory栈里存放的是服务端的activity记录HistoryActivity(class HistoryRecord extendsIApplicationToken.Stub)。处于栈顶的就是当前running状态的activity。
我们来看一下Activity的startActivity方法的请求过程:

从该时序图中可以看出,Activity.startActivity()方法最终是通过代理类和Binder机制,在ActivityManagerService.startActivity方法中执行的。
那么在ActivityManagerService的startActivity中,主要做了那些事情?我们来看下里面比较重要的代码段:
- 根据activity、ProcessRecord等信息创建HistoryRecord实例r
- HistoryRecord r = new HistoryRecord(this, callerApp, callingUid,intent, resolvedType, aInfo, mConfiguration,resultRecord, resultWho, requestCode, componentSpecified);
- 把r加入到mHistory中。
- mHistory.add(addPos, r);
- activity被加入到mHistory之后,只是说明在服务端可以找到该activity记录了,但是在客户端目前还没有该activity记录。还需要通过ProcessRecord中的thread(IApplication)变量,调用它的scheduleLaunchActivity方法在ActivityThread中创建新的ActivityRecord记录(之前我们说过,客户端的activity是用ActivityRecord记录的,并放在mActivities中)。
- app.thread.scheduleLaunchActivity(new Intent(r.intent), r,System.identityHashCode(r), r.info, r.icicle, results, newIntents, !andResume, isNextTransitionForward());
涉及的主要类图:

再来看下ApplicationThread中的scheduleLaunchActivity方法:
- public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Bundle state, List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, boolean notResumed, boolean isForward) { ActivityRecord r = new ActivityRecord(); 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); }
在这个里面主要是根据服务端返回回来的信息创建客户端activity记录ActivityRecord. 并通过Handler发送消息到消息队列,进入消息循环。在ActivityThread.handleMessage()中处理消息。最终在handleLaunchActivity方法中把ActivityRecord记录加入到mActivities(mActivities.put(r.token,r))中,并启动activity(涉及到window、view、windowManager,详情请看handleResumeActivity()方法和上一篇关于window、WindowManager的介绍)
总结:
- 在客户端和服务端分别有一个管理activity的地方,服务端是在mHistory中,处于mHistory栈顶的就是当前处于running状态的activity,客户端是在mActivities中。
- 在startActivity时,首先会在ActivityManagerService中建立HistoryRecord,并加入到mHistory中,然后通过scheduleLaunchActivity在客户端创建ActivityRecord记录并加入到mActivities中。最终在ActivityThread发起请求,进入消息循环,完成activity的启动和窗口的管理等
- from: http://blog.csdn.net/xieqibao/article/details/6570080
【转】Android 之ActivityThead、ActivityManagerService 与activity的管理和创建的更多相关文章
- ActivityManagerService数据结构Activity栈管理(二)
ActivityManagerService要管理四大组件,那四大组件就必须在AMS中有存在的形式,这里先从AMS 如何管理Activity 谈起: Activity在AMS 中存在的形式为Activ ...
- Android解析ActivityManagerService(二)ActivityTask和Activity栈管理
前言 关于AMS,原计划是只写一篇文章来介绍,但是AMS功能繁多,一篇文章的篇幅远远不够.这一篇我们接着来学习与AMS相关的ActivityTask和Activity栈管理. 1.ActivitySt ...
- Android应用程序窗口(Activity)与WindowManagerService服务的连接过程分析
在前两文中,我们分析了Activity组件的窗口对象和视图对象的创建过程.Activity组件在其窗口对象和视图对象创建完成之后,就会请求与WindowManagerService建立一个连接,即请求 ...
- Android应用程序窗口(Activity)的视图对象(View)的创建过程分析
从前文可知道,每一个Activity组件都有一个关联的Window对象,用来描述一个应用程序窗口.每一个应用程序窗口内部又包含有一个View对象,用来描述应用程序窗口的视图.应用程序窗口视图是真正用来 ...
- Android应用程序窗口(Activity)的窗口对象(Window)的创建过程分析(转)
在前文中,我们分析了Android应用程序窗口的运行上下文环境的创建过程.由此可知,每一个Activity组件都有一个关联的ContextImpl对象,同时,它还关联有一个Window对象,用来描述一 ...
- Android应用程序内部启动Activity过程(startActivity)的源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6703247 上文介绍了Android应用程序的 ...
- Android学习笔记——Activity的启动和创建
http://www.cnblogs.com/bastard/archive/2012/04/07/2436262.html Android Activity学习笔记——Activity的启动和创建 ...
- android Application Component研究之Activity(一)
http://blog.csdn.net/windskier/article/details/7096521 终于下定决心写写ActivityManagerService的源码分析的文章了,Activ ...
- android Application Component研究之Activity(二)
http://blog.csdn.net/windskier/article/details/7172710 本文为原创文章,欢迎转载!转载时请注明出处:http://blog.csdn.net/wi ...
随机推荐
- 10 Linux DIG Command Examples for DNS Lookup--reference
by RAMESH NATARAJAN on FEBRUARY 29, 2012 http://www.thegeekstuff.com/2012/02/dig-command-examples/ D ...
- Javascript模块化编程(三)require.js的用法及功能介绍
这个系列的第一部分和第二部分,介绍了Javascript模块原型和理论概念,今天介绍如何将它们用于实战.我采用的是一个非常流行的库require.js感兴趣的朋友可以了解下啊 我采用的是一个非常流行的 ...
- MongoDB集群怎样去访问?
上一章节简单介绍了MONGODB的集群搭建.相信大家都已经很熟悉了.集群搭建完接下来应该考虑我们的程序应该怎样去访问他. 怎么读写数据等操作.下面把我在工作中的一些用法列出来供大家作为参考. 官网的链 ...
- C#中的MD5加密
1 using System.Web.Security; 2 string pswd = FormsAuthentication.HashPasswordForStoringInConfigFile ...
- bootstrap dialog对话框,完成操作提示框
1. 依赖文件: bootstrap.js bootstrap-dialog.js bootstrap.css bootstrap-dialog.css 2.代码 BootstrapDialog.co ...
- C#简单实现读取txt文本文件并分页存储到数组
最近做一个VR项目,需要把某个中草药的介绍信息分页显示到unity场景里然后用VR手柄切换信息. unity的脚本是c#,就先在本地写了个代码测试了一下,利用控制台测试输出,到时候拷贝函数过去再结合交 ...
- Office 365系列(三) -Office 365 Pro plus 安装
这一篇博客主要是说Office 365 Pro plus安装. 1. 当登陆到Office 365以后,点击右边链接“下载软件” 2. 安装最新Office 软件 3. 采用点对点安装,当安装成功以后 ...
- Android图片处理--全景查看效果
PS:Android对于图片处理这块资源还是挺多的,之前用OpenGL制作图片的全景效果,耗时耗力,而且只能点击进去后看到,但是效果是非常的号,今天所写的是编写好的一个图片控件,只要拿来用就可以了.效 ...
- android 5.0 下载编译
CM的CM-12.0版本(对应Android5.0.2): $ repo init -u https://github.com/CyanogenMod/android.git -b cm-12.0 注 ...
- asyncio标准库7 Producer/consumer
使用asyncio.Queue import asyncio import random async def produce(queue, n): for x in range(1, n + 1): ...