http://blog.163.com/hero_213/blog/static/398912142011824248931/

2011-09-02 16:24:10|分类: Android |标签: |字号订阅

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

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

Android 之ActivityThead、ActivityManagerService 与activity的管理和创建_第1张图片

ActivityThread:

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

view plain
  1. finalHashMap<IBinder,ActivityRecord>mActivities=newHashMap<IBinder,ActivityRecord>();

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

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

view plain
  1. /***应用程序的启动入口.,主线程在启动的时候系统会自动建立消息循环机制。*/publicstaticfinalvoidmain(String[]args){SamplingProfilerIntegration.start();Process.setArgV0("<pre-initialized>");Looper.prepareMainLooper();ActivityThreadthread=newActivityThread();thread.attach(false);Looper.loop();if(Process.supportsProcesses()){thrownewRuntimeException("Mainthreadloopunexpectedlyexited");}thread.detach();Stringname=(thread.mInitialApplication!=null)?thread.mInitialApplication.getPackageName():"<unknown>";Slog.i(TAG,"Mainthreadof"+name+"isnowexiting");}

在建立消息循环之前,会通过thread.attach(false)来初始化应用程序的运行环境,并建立activityThreadActivityManagerService之间的桥mAppThread, mAppThreadIApplicationThread的一个实例。

view plain
  1. android.ddm.DdmHandleAppName.setAppName("<pre-initialized>");RuntimeInit.setApplicationObject(mAppThread.asBinder());IActivityManagermgr=ActivityManagerNative.getDefault();try{mgr.attachApplication(mAppThread);}catch(RemoteExceptionex){}

注意:每个应用程序对应着一个ActivityThread实例,应用程序由ActivityThread.main打开消息循环。每个应用程序同时也对应着一个ApplicationThread对象。该对象是activityThreadActivityManagerService之间的桥梁。

attach中还做了一件事情,就是通过代理调用attachApplication,并利用bindertransact机制,在ActivityManagerService中建立了ProcessRecord信息。

Android 之ActivityThead、ActivityManagerService 与activity的管理和创建_第2张图片

之后通过该ProcessRecord就可以获得该ActivityThread中的所有ActivityRecord记录。下面会介绍。

ActivityManagerService:

ActivityManagerService中,也有一个用来管理activity的地方:mHistory栈,这个mHistory栈里存放的是服务端的activity记录HistoryActivity(class HistoryRecord extendsIApplicationToken.Stub)。处于栈顶的就是当前running状态的activity

我们来看一下ActivitystartActivity方法的请求过程:

Android 之ActivityThead、ActivityManagerService 与activity的管理和创建_第3张图片

从该时序图中可以看出,Activity.startActivity()方法最终是通过代理类和Binder机制,在ActivityManagerService.startActivity方法中执行的。

那么在ActivityManagerServicestartActivity中,主要做了那些事情?我们来看下里面比较重要的代码段:

  • 根据activityProcessRecord等信息创建HistoryRecord实例r
    view plain
    1. HistoryRecordr=newHistoryRecord(this,callerApp,callingUid,intent,resolvedType,aInfo,mConfiguration,resultRecord,resultWho,requestCode,componentSpecified);

  • r加入到mHistory中。
    view plain
    1. mHistory.add(addPos,r);
  • activity被加入到mHistory之后,只是说明在服务端可以找到该activity记录了,但是在客户端目前还没有该activity记录。还需要通过ProcessRecord中的threadIApplication)变量,调用它的scheduleLaunchActivity方法在ActivityThread中创建新的ActivityRecord记录(之前我们说过,客户端的activity是用ActivityRecord记录的,并放在mActivities中)。 view plain
    1. app.thread.scheduleLaunchActivity(newIntent(r.intent),r,System.identityHashCode(r),r.info,r.icicle,results,newIntents,!andResume,isNextTransitionForward());

涉及的主要类图:

Android 之ActivityThead、ActivityManagerService 与activity的管理和创建_第4张图片

再来看下ApplicationThread中的scheduleLaunchActivity方法:

view plain
  1. publicfinalvoidscheduleLaunchActivity(Intentintent,IBindertoken,intident,ActivityInfoinfo,Bundlestate,List<ResultInfo>pendingResults,List<Intent>pendingNewIntents,booleannotResumed,booleanisForward){ActivityRecordr=newActivityRecord();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(涉及到windowviewwindowManager,详情请看handleResumeActivity()方法和上一篇关于windowWindowManager的介绍)

总结:

  1. 在客户端和服务端分别有一个管理activity的地方,服务端是在mHistory中,处于mHistory栈顶的就是当前处于running状态的activity,客户端是在mActivities中。
  2. startActivity时,首先会在ActivityManagerService中建立HistoryRecord,并加入到mHistory中,然后通过scheduleLaunchActivity在客户端创建ActivityRecord记录并加入到mActivities中。最终在ActivityThread发起请求,进入消息循环,完成activity的启动和窗口的管理等
  3. (3)ActivityThread端的activity信息全部被存储在ActivityThread的成员变量mActivities中,在mActivities中,记录了应用程序创建的所有activity实例记录,对应的是ActivityRecord。

    finalHashMap<IBinder,ActivityRecord>mActivities=newHashMap<IBinder,ActivityRecord>();

    ActivityThread与ActivityManagerService关系图如下:



    (1) 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); //发送消息给ActivityThread.handleMessage()中处理

    }

    public void handleMessage(Message msg) {

    switch (msg.what) {

    case LAUNCH_ACTIVITY: {

    ActivityRecord r = (ActivityRecord)msg.obj;

    r.packageInfo = getPackageInfoNoCheck(

    r.activityInfo.applicationInfo);

    handleLaunchActivity(r, null);

    } break;

    。。。。。。

    }

    scheduleLaunchActivity调用时会使用消息队列的方式调用到handleMessage函数,同时handleMessage会调用 handleLaunchActivity,此函数的作用主要是将activity信息加入到mActivity中同时启动activity,启动 activity时涉及到window、view、windowManager相关知识



更多相关文章

  1. 我的Android 4 学习系列之创建应用程序和Activity:Manifest、Appl
  2. Android控件阴影效果的几种实现方法
  3. Android 应用程序中使用 Internet 数据(XML、JSON 和 protocol bu
  4. PHP开发Android应用程序
  5. Android应用程序核心-应用程序的基本组件
  6. Android 应用程序中-设置-蓝牙,若隐藏蓝牙功能
  7. Android VideoView设置静音,Android 设置VideoView静音,Android
  8. ListView去掉分割线的几种方法

随机推荐

  1. android打开系统联系人界面
  2. 关于Android分辨率的支持
  3. Android中的文件权限操作
  4. textview cannot be resolved to a type
  5. android页面或组件动画(比如淡出、3D翻转
  6. Android 判断网络状态,并且在没有网络的时
  7. Android(安卓)实现长按弹出PopupMenu 菜
  8. Android(安卓)简单音乐播放器开发
  9. Android三种定位方式
  10. android xml中?和 @