在android中,Activity是四大组件中比较重要的一个(当然其他的也比较重要),那么android中是怎样管理这些activity的?应用的进程和主线程是怎么创建的,应用的消息循环又是在什么时候创建的?在这篇文章中将详细介绍:

先来看下涉及到的类,通过以下类图对整体先有个大概的印象:

ActivityThread:

ActivityThread主要用来启动应用程序的主线程,并且管理在应用端跟用户打交道的activity。在应用端的activity信息全部被存储在ActivityThread的成员变量mActivities中。

  1. final HashMap<IBinder, ActivityRecord> mActivities= new  HashMap<IBinder, ActivityRecord>();

也就是说,在mActivities中,记录了应用程序创建的所有activity实例记录,对应的是ActivityRecord。

ActivityThread是怎么启动应用程序的呢?ActivityThread中有一个main函数,在这个里面,将启动应用程序并建立消息循环。在之前也介绍过,系统会为主线程自动创建消息循环。

  1. /*** 应用程序的启动入口 . ,主线程在启动的时候系统会自动建立消息循环机制。*/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的一个实例。

  1. 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
  1. HistoryRecord r = new HistoryRecord(this, callerApp, callingUid,intent, resolvedType, aInfo, mConfiguration,resultRecord, resultWho, requestCode, componentSpecified);
  • 把r加入到mHistory中。
  1. mHistory.add(addPos, r);
    • activity被加入到mHistory之后,只是说明在服务端可以找到该activity记录了,但是在客户端目前还没有该activity记录。还需要通过ProcessRecord中的thread(IApplication)变量,调用它的scheduleLaunchActivity方法在ActivityThread中创建新的ActivityRecord记录(之前我们说过,客户端的activity是用ActivityRecord记录的,并放在mActivities中)。
  1. app.thread.scheduleLaunchActivity(new Intent(r.intent), r,System.identityHashCode(r),                    r.info, r.icicle, results, newIntents, !andResume,                    isNextTransitionForward());

涉及的主要类图:

再来看下ApplicationThread中的scheduleLaunchActivity方法:

  1. 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的介绍)

总结:

  1. 在客户端和服务端分别有一个管理activity的地方,服务端是在mHistory中,处于mHistory栈顶的就是当前处于running状态的activity,客户端是在mActivities中。
  2. 在startActivity时,首先会在ActivityManagerService中建立HistoryRecord,并加入到mHistory中,然后通过scheduleLaunchActivity在客户端创建ActivityRecord记录并加入到mActivities中。最终在ActivityThread发起请求,进入消息循环,完成activity的启动和窗口的管理等
  3. from: http://blog.csdn.net/xieqibao/article/details/6570080

【转】Android 之ActivityThead、ActivityManagerService 与activity的管理和创建的更多相关文章

  1. ActivityManagerService数据结构Activity栈管理(二)

    ActivityManagerService要管理四大组件,那四大组件就必须在AMS中有存在的形式,这里先从AMS 如何管理Activity 谈起: Activity在AMS 中存在的形式为Activ ...

  2. Android解析ActivityManagerService(二)ActivityTask和Activity栈管理

    前言 关于AMS,原计划是只写一篇文章来介绍,但是AMS功能繁多,一篇文章的篇幅远远不够.这一篇我们接着来学习与AMS相关的ActivityTask和Activity栈管理. 1.ActivitySt ...

  3. Android应用程序窗口(Activity)与WindowManagerService服务的连接过程分析

    在前两文中,我们分析了Activity组件的窗口对象和视图对象的创建过程.Activity组件在其窗口对象和视图对象创建完成之后,就会请求与WindowManagerService建立一个连接,即请求 ...

  4. Android应用程序窗口(Activity)的视图对象(View)的创建过程分析

    从前文可知道,每一个Activity组件都有一个关联的Window对象,用来描述一个应用程序窗口.每一个应用程序窗口内部又包含有一个View对象,用来描述应用程序窗口的视图.应用程序窗口视图是真正用来 ...

  5. Android应用程序窗口(Activity)的窗口对象(Window)的创建过程分析(转)

    在前文中,我们分析了Android应用程序窗口的运行上下文环境的创建过程.由此可知,每一个Activity组件都有一个关联的ContextImpl对象,同时,它还关联有一个Window对象,用来描述一 ...

  6. Android应用程序内部启动Activity过程(startActivity)的源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6703247 上文介绍了Android应用程序的 ...

  7. Android学习笔记——Activity的启动和创建

    http://www.cnblogs.com/bastard/archive/2012/04/07/2436262.html Android Activity学习笔记——Activity的启动和创建 ...

  8. android Application Component研究之Activity(一)

    http://blog.csdn.net/windskier/article/details/7096521 终于下定决心写写ActivityManagerService的源码分析的文章了,Activ ...

  9. android Application Component研究之Activity(二)

    http://blog.csdn.net/windskier/article/details/7172710 本文为原创文章,欢迎转载!转载时请注明出处:http://blog.csdn.net/wi ...

随机推荐

  1. java多线程-Lock

    大纲: Lock接口 synchronized&Lock异同 一.Lock public interface Lock { void lock(); void lockInterruptibl ...

  2. 智能手表ticwatch穿戴体验

    前言 可穿戴设备近几年越来越火,最开始是谷歌眼睛.手环,再到手表.VR眼镜,相信未来几年这片领域依旧火热~ 自从谷歌发布Android Wear.苹果发布Apple Watch之后,智能手表的战役就正 ...

  3. SpringBoot 思维导图

  4. How to add more to Git Bash on Windows

    How to add more to Git Bash on Windows Download the lastest wget binary for windows from https://ete ...

  5. JUnit异常断言

    使用Junit时,有多种方式来进行异常的断言 ExeceptedException & @Rule,可以同时断言异常类型和消息 public class ExpectedExceptionsT ...

  6. 搭建基于Ubuntu的开发环境

    基于ubuntu 16.04 LTS经验 分区方案 内存:4G,硬盘:500G 分区 大小 说明 备注 / 20G 说明 swap 6G 说明 /tmp 15G 临时文件 /var 40G 可变数据目 ...

  7. 使用windows的BitLocker+VHD加密“文件夹”

    进入磁盘管理 创建VHD,选定位置 初始化创建的虚拟盘,新建简单卷 给新的盘启用BitLocker 其他: 快速锁定:manage-bde.exe D: -lock  -fd

  8. centOS使用.htaccess

    首先,你要保证你的Aapche已经开启了.htaccess 可以参考:http://www.veryhuo.com/a/view/21259.html 以下是.htaccess文件中的内容: Rewr ...

  9. SQL Server Profiler(转载)

    SQL Server Profiler工具 一.SQL Profiler工具简介 SQL Profiler是一个图形界面和一组系统存储过程,其作用如下: 图形化监视SQL Server查询: 在后台收 ...

  10. MyBatis 中 sqlmapconfig核心标签typeAliases配置说明

    标签说明 在 MyBatis 的 sql 映射配置文件中,需要使用 paramterType.resultType 来设置 sql 语句的输入输出参数,一般参数都是基本的数据类型或封装类型,但都需要声 ...