求知 文章 文库 Lib 视频 iProcess 课程 角色 咨询 工具 讲座 Modeler   Code  
会员   
 
  
每天15篇文章
不仅获得谋生技能
更可以追随信仰
 
 
     
   
分享到
Activity的启动流程
 

作者:dragondog,发布于2012-2-17

 

以前看了很多,时间长了都忘了,所以还是勤快点,把看到的都记下来,算是给自己点积累。

Activity启动分为很多种情况,这里说的是打开新的应用程序第一个Activity的流程。

1. AcitivityManager产生新进程,新进程从android.app.ActivityThread.main开始运行。这里就是一般意义上的程序入口点,类似于C的main函数。

ActivityManagerService.java

private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr) {

    // Process里面通知Zygote服务,Zygote真正产生新的进程(准确说是复制一个)

    int pid = Process.start("android.app.ActivityThread",
             mSimpleProcessManagement ? app.processName : null, uid, uid,

}

2.ActivityThread的main函数中将Looper准备起来,prepareMainLooper标志着这是应用程序主线程的Looper对象。

ActivityThread.java

public static final void main(String[] args) {

    Looper.prepareMainLooper();

    ActivityThread thread = new ActivityThread();
        thread.attach(false);
        // 这里闭合消息循环
        Looper.loop();

}

3. 接下来调用attach,参数为false,表明这不是系统进程,是给普通应用程序用使用的进程。

ActivityThread.java

private final void attach(boolean system) {

    ViewRoot.addFirstDrawHandler(new Runnable() {
            public void run() {
                ensureJitEnabled();
            }
        });
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        IActivityManager mgr = ActivityManagerNative.getDefault();
        mgr.attachApplication(mAppThread);

}

mAppThread是ApplicationThread对象,是提供给ActivityManagerService控制ActivityThread的回调接口。

private final class ApplicationThread extends ApplicationThreadNative {

    public final void schedulePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges){

        queueOrSendMessage(finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
            token, (userLeaving ? 1 : 0), configChanges);
        }

    public final void scheduleStopActivity(IBinder token, boolean showWindow, int configChanges) {
            queueOrSendMessage(showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
            token, 0, configChanges);
        }

    .........

}

ActivityManagerService要Pause当前Activity,就会调用schedulePauseActivity想本地的消息循环中加入一个H.PAUSE_ACTIVITY的消息,然后立即返回以避免ActivityManagerService的阻塞。

4.现在又回到了ActivityManagerService中

ActivityManagerService.java

// ActivityManagerService中XXXLocked函数才是真正干活的地方,XXX只是个套

public final void attachApplication(IApplicationThread thread) {
        int callingPid = Binder.getCallingPid();
        attachApplicationLocked(thread, callingPid);
    }

private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {

    // 这里取出对应该Pid的ProcessRecord对象,如果取不出来,你就等着out吧

    app = mPidsSelfLocked.get(pid)

    // 为ProcessRecord对象补充信息

    app.thread = thread;
        app.curAdj = app.setAdj = -100;
        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
        app.forcingToForeground = null;
        app.foregroundServices = false;
        app.debugging = false;
        // 清除timeout监测
        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);

    // 回调之前的ActivityThread,让它记住自己在ActivityManagerService中的相关信息,传这么大坨东西,真给力

    thread.bindApplication(processName, app.instrumentationInfo != null
        app.instrumentationInfo : app.info, providers,
        app.instrumentationClass, app.instrumentationProfileFile,
        app.instrumentationArguments, app.instrumentationWatcher, testMode,
        isRestrictedBackupMode || !normalMode,
        mConfiguration, getCommonServicesLocked());

    // topRunningActivityLocked的意思没看太明白

    HistoryRecord hr = topRunningActivityLocked(null);

    // 启动Activity

    realStartActivityLocked(hr, app, true, true);

}

private final boolean realStartActivityLocked(HistoryRecord r,
    ProcessRecord app, boolean andResume, boolean checkConfig){

    // 这里又跑到ActivityThread中去了

    app.thread.scheduleLaunchActivity(new Intent(r.intent), r, System.identityHashCode(r),
        r.info, r.icicle, results, newIntents, !andResume, isNextTransitionForward());

}

5.ActivityThread开始调度用户的Activity启动了

ActivityThread.java

private final void handleLaunchActivity(ActivityRecord r, Intent customIntent) {
        Activity a = performLaunchActivity(r, customIntent);

    ......

}

private final void performLaunchActivity(ActivityRecord r, Intent customIntent) {

    java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
        // 产生Activity
        activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);

    // 将新生的Activity与当前应用关联

    activity.attach(appContext, this, getInstrumentation(), r.token,
        r.ident, app, r.intent, r.activityInfo, title, r.parent,
        r.embeddedID, r.lastNonConfigurationInstance,
        r.lastNonConfigurationChildInstances, config);

    .....

}

6.Acivity与当前App关联,直到这里,平时应用所见的Activity才真正被构建

Actiivty.java

final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token, int ident,
    Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id,
    Object lastNonConfigurationInstance, HashMap<String,Object> lastNonConfigurationChildInstances,
    Configuration config) {

    // 记录传入ContexImpl实例,这就是平时所见的Activity Context
        attachBaseContext(context);
        // 创建与Activity关联的Window,可以简单理解为显示窗口
        mWindow = PolicyManager.makeNewWindow(this);

    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;
        // 构建WindowManager的代理LocalWindowManager
        mWindow.setWindowManager(null, mToken, mComponent.flattenToString());
        if (mParent != null) {
            // 难道说整个Activity栈中的Activity都有同一个Container
            mWindow.setContainer(mParent.getWindow());
     }
     mWindowManager = mWindow.getWindowManager();

}

7.ActivityThread

ActivityThread.java

private final void performLaunchActivity(ActivityRecord r, Intent customIntent) {

     ......

     // 回调Activity::onCreate

     mInstrumentation.callActivityOnCreate(activity, r.state);

    // 记录新产生的Activity
         mActivities.put(r.token, r);

}

private final void handleLaunchActivity(ActivityRecord r, Intent customIntent) {

    ......

    handleResumeActivity(r.token, false, r.isForward);

}

final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) {
    ActivityRecord r = performResumeActivity(token, clearHide);

}

public final ActivityRecord performResumeActivity(IBinder token, boolean clearHide) {

    if (r.pendingIntents != null) {
            deliverNewIntents(r, r.pendingIntents);
             r.pendingIntents = null;
         }
        if (r.pendingResults != null) {
            deliverResults(r, r.pendingResults);
            r.pendingResults = null;
        }
        //回调Activity::onResume
        r.activity.performResume();

}

到这里,Activity从产生到初始化的过程就全部结束了。之后就是等待用户界面的消息,根据消息进行相应的处理。整个过程中,在ActivityManagerServer、ActivityThread的互相协作下构建出Activity,并在相应的时机回调Activity的相应接口,完成Activity的初始化。


相关文章 相关文档 相关课程



深度解析:清理烂代码
如何编写出拥抱变化的代码
重构-使代码更简洁优美
团队项目开发"编码规范"系列文章
重构-改善既有代码的设计
软件重构v2
代码整洁之道
高质量编程规范
基于HTML5客户端、Web端的应用开发
HTML 5+CSS 开发
嵌入式C高质量编程
C++高级编程

 
分享到
 
 
     


android人机界面指南
Android手机开发(一)
Android手机开发(二)
Android手机开发(三)
Android手机开发(四)
iPhone消息推送机制实现探讨
手机软件测试用例设计实践
手机客户端UI测试分析
手机软件自动化测试研究报告
更多...   


Android高级移动应用程序
Android应用开发
Android系统开发
手机软件测试
嵌入式软件测试
Android软、硬、云整合


领先IT公司 android开发平台最佳实践
北京 Android开发技术进阶
某新能源领域企业 Android开发技术
某航天公司 Android、IOS应用软件开发
阿尔卡特 Linux内核驱动
艾默生 嵌入式软件架构设计
西门子 嵌入式架构设计
更多...   
 
 
 
 
 
每天2个文档/视频
扫描微信二维码订阅
订阅技术月刊
获得每月300个技术资源
 
 

关于我们 | 联系我们 | 京ICP备10020922号 京公海网安备110108001071号