Activity的工作过程(二)

Activity启动详细流程(下)

四. 新进程启动ActivityThread

image

  1. Zygote进程孵化出新的应用进程后,会执行ActivityThread类的main方法。
  2. 在该方法里会先准备好Looper和消息队列,然后调用attach方法将应用进程绑定到ActivityManagerService。
  3. 然后进入loop循环,不断地读取消息队列里的消息,并分发消息。

    //ActivityThread类
    public static void main(String[] args) {
        //... 
        Looper.prepareMainLooper();
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        AsyncTask.init();
        //...
        Looper.loop();
        //...
    }
五. 应用进程绑定到ActivityManagerService

image

  1. 在ActivityThread的main方法里调用thread.attach(false);

    attach方法的主要代码如下所示:

    //ActivityThread类
    private void attach(boolean system) {
        sThreadLocal.set(this);
        mSystemThread = system;
        if (!system) {
            //...
            IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
            //调用ActivityManagerService的attachApplication方法
            //将ApplicationThread对象绑定至ActivityManagerService,
            //这样ActivityManagerService就可以
            //通过ApplicationThread代理对象控制应用进程
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                // Ignore
            }
        } else {
            //...
        }
        //... 
    }
  2. ActivityManagerService的attachApplication方法执行attachApplicationLocked(thread, callingPid)进行绑定。

    //ActivityManagerService类
    private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) { 
        ProcessRecord app;
        //...     
        app.thread = thread; 
        //...  
        try {
            //...
            thread.bindApplication(processName, appInfo, providers,
                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
                    mCoreSettingsObserver.getCoreSettingsLocked());
            //... 
        } catch (Exception e) {
           //...
        }
        //... 
        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
        if (hr != null && normalMode) {
            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                    && processName.equals(hr.processName)) {
                try {
                    if (mHeadless) {
                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
                    //mMainStack.realStartActivityLocked真正启动activity
                        didSomething = true;
                    }
                } catch (Exception e) {
                    //...
                }
            } else {
                //...
            }
        }
        //... 
        return true;
    }
  3. attachApplicationLocked方法有两个重要的函数调用thread.bindApplicationmMainStack.realStartActivityLocked

    • thread.bindApplication将应用进程的ApplicationThread对象绑定到ActivityManagerService,也就是说获得ApplicationThread对象的代理对象。
    • mMainStack.realStartActivityLocked通知应用进程启动Activity。
  4. thread.bindApplication

    • thread对象其实是ActivityThreadApplicationThread对象在ActivityManagerService的代理对象,故此执行thread.bindApplication,最终会调用ApplicationThreadbindApplication方法,该方法的主要代码如下所示:
    //ActivityThreadpublic final void bindApplication(String processName,
            ApplicationInfo appInfo, List<ProviderInfo> providers,
            ComponentName instrumentationName, String profileFile,
            ParcelFileDescriptor profileFd, boolean autoStopProfiler,
            Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
            int debugMode, boolean enableOpenGlTrace, boolean isRestrictedBackupMode,
            boolean persistent, Configuration config, CompatibilityInfo compatInfo,
            Map<String, IBinder> services, Bundle coreSettings) {
        //...  
        AppBindData data = new AppBindData();
        data.processName = processName;
        data.appInfo = appInfo;
        data.providers = providers;
        data.instrumentationName = instrumentationName;
        data.instrumentationArgs = instrumentationArgs;
        data.instrumentationWatcher = instrumentationWatcher;
        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);
    }
    • 这样调用queueOrSendMessage会往ActivityThread的消息队列发送消息,消息的用途是BIND_APPLICATION
    • 这样会在handler里处理BIND_APPLICATION消息,接着调用handleBindApplication方法处理绑定消息:

      //ActivityThread类
      private void handleBindApplication(AppBindData data) {
        //...  
        ApplicationInfo instrApp = new ApplicationInfo();
        instrApp.packageName = ii.packageName;
        instrApp.sourceDir = ii.sourceDir;
        instrApp.publicSourceDir = ii.publicSourceDir;
        instrApp.dataDir = ii.dataDir;
        instrApp.nativeLibraryDir = ii.nativeLibraryDir;
        LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
              appContext.getClassLoader(), false, true);
        ContextImpl instrContext = new ContextImpl();
        instrContext.init(pi, null, this);
          //... 
        if (data.instrumentationName != null) {
             //...
        } else {
             //注意Activity的所有生命周期方法都会被Instrumentation对象所监控,
             //也就说执行Activity的生命周期方法前后一定会调用Instrumentation对象的相关方法
             //并不是说只有跑单测用例才会建立Instrumentation对象,
             //即使不跑单测也会建立Instrumentation对象
             mInstrumentation = new Instrumentation();
        }
        //... 
        try {
           //...
           Application app = data.info.makeApplication(data.restrictedBackupMode, null);
           mInitialApplication = app;
           //...         
           try {
                mInstrumentation.onCreate(data.instrumentationArgs);
            }catch (Exception e) {
                   //...
            }
            try {
                 //这里会调用Application的onCreate方法
                 //故此Applcation对象的onCreate方法会比ActivityThread的main方法后调用
                 //但是会比这个应用的所有activity先调用
                  mInstrumentation.callApplicationOnCreate(app);
              } catch (Exception e) {
                 //...
              }
          } finally {
              StrictMode.setThreadPolicy(savedPolicy);
          }
      }
  5. mMainStack.realStartActivityLocked

    1. realStartActivity会调用scheduleLaunchActivity启动activity,主要代码:

      //ActivityStack类
      final boolean realStartActivityLocked(ActivityRecord r,
              ProcessRecord app, boolean andResume, boolean checkConfig)
              throws RemoteException {
          //...  
          try {
              //...
              app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                      System.identityHashCode(r), r.info,
                      new Configuration(mService.mConfiguration),
                      r.compat, r.icicle, results, newIntents, !andResume,
                      mService.isNextTransitionForward(), profileFile, profileFd,
                      profileAutoStop);
              //...
          } catch (RemoteException e) {
              //...
          }
          //...    
          return true;
      }
    2. 同样app.thread也只是ApplicationThread对象在ActivityManagerService的一个代理对象而已,最终会调用ApplicationThreadscheduleLaunchActivity方法。

      //ActivityThread类
      public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
              ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
              Bundle state, List<ResultInfo> pendingResults,
              List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
              String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
          ActivityClientRecord r = new ActivityClientRecord();
          r.token = token;
          r.ident = ident;
          r.intent = intent;
          r.activityInfo = info;
          r.compatInfo = compatInfo;
          r.state = state;
          r.pendingResults = pendingResults;
          r.pendingIntents = pendingNewIntents;
          r.startsNotResumed = notResumed;
          r.isForward = isForward;
          r.profileFile = profileName;
          r.profileFd = profileFd;
          r.autoStopProfiler = autoStopProfiler;
          updatePendingConfiguration(curConfig);
          queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
      }
    3. 这里调用了queueOrSendMessageActivityThread的消息队列发送了消息,消息的用途是启动Activity,接下来ActivityThreadhandler便会处理该消息。
六. ActivityThread的Handler处理启动Activity的消息

image

  1. ActivityThread的handler调用handleLaunchActivity处理启动Activity的消息,handleLaunchActivity的主要代码如下所示:

    //ActivityThread类
    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        //... 
        Activity a = performLaunchActivity(r, customIntent);
        if (a != null) {
            //...
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed);
            //...
        } else {
            //...
        }
    }
    • handleLaunchActivity方法里有有两个重要的函数调用,performLaunchActivity和handleResumeActivity,
    • performLaunchActivity会调用ActivityonCreate,onStart,onResotreInstanceState方法,
    • handleResumeActivity会调用ActivityonResume方法.
  2. performLaunchActivity的主要代码如下所示:

    //ActivityThread类
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        //...
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            //...
        } catch (Exception e) {
            //...
        }
        try {
            //r.packageInfo.makeApplication实际并未创建Application对象,
            //因为bindApplication过程已经创建了Application对象,
            //makeApplication方法会返回已创建的Application对象
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
            //...         
            if (activity != null) {
                //...
                //将application对象,appContext对象绑定到新建的activity对象
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config);
                //... 
                //会调用Activity的onCreate方法             
                mInstrumentation.callActivityOnCreate(activity, r.state);
                //...
                //...
                //调用Activity的onStart方法
                if (!r.activity.mFinished) {
                    activity.performStart();
                    r.stopped = false;
                }              
                if (!r.activity.mFinished) {
                    if (r.state != null) {
                        //会调用Activity的onRestoreInstanceState方法
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                    }
                }
                if (!r.activity.mFinished) {
                    activity.mCalled = false;
                    mInstrumentation.callActivityOnPostCreate(activity, r.state);
                    //...
                }
            }
            //...
        } catch (SuperNotCalledException e) {
            throw e;
        } catch (Exception e) {
            //...
        }
        return activity;
    }
  3. handleResumeActivity的主要代码如下所示:

    //ActivityThread类
    final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
            boolean reallyResume) {
        //...
        //performResumeActivity最终会调用Activity的onResume方法 
        ActivityClientRecord r = performResumeActivity(token, clearHide);
        if (r != null) {
            final Activity a = r.activity;
            //... 
            //显示界面
            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;
                    wm.addView(decor, l);
                }
               //...         
            } else if (!willBeVisible) {
                 //...
            }
            // Tell the activity manager we have resumed.
            if (reallyResume) {
                try {
                    ActivityManagerNative.getDefault().activityResumed(token);
                } catch (RemoteException ex) {
                }
            }
        } else {
             //...
        }
    }
  4. performResumeActivity的主要代码如下所示:

    //ActivityThread类
    public final ActivityClientRecord performResumeActivity(IBinder token,
            boolean clearHide) {
        ActivityClientRecord r = mActivities.get(token);
        //...
        if (r != null && !r.activity.mFinished) {
             //...
            try {
                //... 
                //会调用Activity的onResume方法 
                r.activity.performResume();
                //...
            } catch (Exception e) {
                //...
            }
        }
        return r;
    }
七. 总结
  1. Activity的启动流程:

    1. 用户在Launcher程序里点击应用图标时,会通知ActivityManagerService启动应用的入口Activity,
    2. ActivityManagerService发现这个应用还未启动,则会通知Zygote进程孵化出应用进程,然后在这个dalvik应用进程里执行ActivityThreadmain方法。
    3. 应用进程接下来通知ActivityManagerService应用进程已启动,ActivityManagerService保存应用进程的一个代理对象,这样ActivityManagerService可以通过这个代理对象控制应用进程,然后ActivityManagerService通知应用进程创建入口Activity的实例,并执行它的生命周期方法.
  2. 现在也可以理解:

    1. 如果应用的组件(包括所有组件Activity,Service,ContentProvider,Receiver) 被启动,肯定会先启动以应用包名为进程名的进程,这些组件都会运行在应用包名为进程名的进程里,并且是在主线程里。
    2. 应用进程启动时会先创建Application对象,并执行Application对象的生命周期方法,然后才启动应用的组件。
  3. 有一种情况比较特殊,那就是为组件设置了特殊的进程名,也就是说通过android:process设置进程名的情况,此时组件运行在单独的进程内。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值