Android应用程序启动过程下

在前面我们已经知道Zygote里面fork一个进程作为app的进程,在ActivityManagerService里面的startProcessLocked方法里面有一个processName(android.app.ActivityThread),就是创建进程后的入口,进入到ActivityThread里面。

public static void main(String[] args) {

        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        Looper.loop();

    }

看到这里我想说,如果你研究过Handler,肯定很熟悉,为啥主线程handler可以直接发送消息,原因就在这里。每创建一个进程都会创建一个ActivityThread实例。进入attach

private void attach(boolean system) {
     if (!system) {

       final IActivityManager mgr = ActivityManagerNative.getDefault();
         try {
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
        ...
     }
}

获取到ActivityManagerService并将ApplicationThread传到AMS里面,进入到ActivityManagerService.attachApplication();

@Override
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }

获取到pid进入到attachApplicationLocked

  private final boolean attachApplicationLocked(IApplicationThread thread,int pid) {
 ProcessRecord app;
        if (pid != MY_PID && pid >= 0) {
            synchronized (mPidsSelfLocked) {
                app = mPidsSelfLocked.get(pid);
         }
    //如果当前进程有以前的记录,全部清除
     if (app.thread != null) {
            handleAppDiedLocked(app, true, true);
     }
     ...
        app.makeActive(thread, mProcessStats);
        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
        app.forcingToForeground = null;
        updateProcessForegroundLocked(app, false, false);
        app.hasShownUi = false;
        app.debugging = false;
        app.cached = false;
        app.killedByAm = false;
     ...
  thread.bindApplication( ... );

    ....

     try {
         if (mStackSupervisor.attachApplicationLocked(app)) {
              didSomething = true;
          }
      } catch (Exception e) {
          Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
          badApp = true;
      }
}

对新的进程进行初始化,回到ApplicationThread.bindApplication()绑定application。

 public final void bindApplication(String processName, ApplicationInfo appInfo,
                List<ProviderInfo> providers, ComponentName instrumentationName,
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableBinderTracking, boolean trackAllocation,
                boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                CompatibilityInfo compatInfo, Map<String, IBinder> services, Bundle coreSettings) {

            if (services != null) {
                // Setup the service cache in the ServiceManager
                ServiceManager.initServiceCache(services);
            }

            setCoreSettings(coreSettings);

            AppBindData data = new AppBindData();
            data.processName = processName;
            data.appInfo = appInfo;
            data.providers = providers;
            data.instrumentationName = instrumentationName;
            data.instrumentationArgs = instrumentationArgs;
            data.instrumentationWatcher = instrumentationWatcher;
            data.instrumentationUiAutomationConnection = instrumentationUiConnection;
            data.debugMode = debugMode;
            data.enableBinderTracking = enableBinderTracking;
            data.trackAllocation = trackAllocation;
            data.restrictedBackupMode = isRestrictedBackupMode;
            data.persistent = persistent;
            data.config = config;
            data.compatInfo = compatInfo;
            data.initProfilerInfo = profilerInfo;
            sendMessage(H.BIND_APPLICATION, data);
        }

通过handler发送消息到主线程调用handleBindApplication(data);

 private void handleBindApplication(AppBindData data) {
 ...
   try {
   //实例化Instrumentation,找一个进程中只会有一个实例
        final ClassLoader cl = instrContext.getClassLoader();
         mInstrumentation = (Instrumentation)cl.loadClass(data.instrumentationName.getClassName()).newInstance();
   } catch (Exception e) {  }
...


   // If the app is being launched for full backup or restore, bring it up in
      // a restricted environment with the base application class.
      //实例化Application
      Application app = data.info.makeApplication(data.restrictedBackupMode, null);
       mInitialApplication = app;
       if (!data.restrictedBackupMode) {
           if (!ArrayUtils.isEmpty(data.providers)) {
               installContentProviders(app, data.providers); 
               mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
           }
       }

      try {
            mInstrumentation.onCreate(data.instrumentationArgs);
        }
        catch (Exception e) {  }
        try {
             mInstrumentation.callApplicationOnCreate(app);
         } catch (Exception e) {
             if (!mInstrumentation.onException(app, e)) {
                 throw new RuntimeException(
                     "Unable to create application " + app.getClass().getName()
                     + ": " + e.toString(), e);
             }
         }
         ...

}

//调用我们熟悉的Application里面的onCreate方法。
   public void callApplicationOnCreate(Application app) {
        app.onCreate();
    }

//最终创建Application,创建后调用attach
  static public Application newApplication(Class<?> clazz, Context context)
        throws InstantiationException, IllegalAccessException, 
        ClassNotFoundException {
    Application app = (Application)clazz.newInstance();
    app.attach(context);
    return app;
}
 final void attach(Context context) {
      attachBaseContext(context);
      mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
  }

从上面来看,先是实例化Application,然后app.attach(context),attach里面调用 attachBaseContext(context);最后才是调用 app.onCreate(),这就是我们经常使用Application的生命周期。

上面在ActivityMangerService通过attachApplicationLocked方法,远程进入到ApplicationThread里面的bindApplication方法,
然后发送消息到主线程创建application,并调用其生命周期。接着我们回到attachApplicationLocked方法,进入ActivityStackSupervisor.attachApplicationLocked()

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        final String processName = app.processName;
        boolean didSomething = false;
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (!isFocusedStack(stack)) {
                    continue;
                }
                ActivityRecord hr = stack.topRunningActivityLocked();
                if (hr != null) {
                    if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                            && processName.equals(hr.processName)) {
                        try {
                            if (realStartActivityLocked(hr, app, true, true)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                            Slog.w(TAG, "Exception in new application when starting activity "
                                  + hr.intent.getComponent().flattenToShortString(), e);
                            throw e;
                        }
                    }
                }
            }
        }
        if (!didSomething) {
            ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
        }
        return didSomething;
    }

这里获取到要创建的activity,后调用realStartActivityLocked(…)去创建,这个方法很熟悉,因为在前面startSpecificActivityLocked()创建进程判断时候出现过,如果进程存在就直接去调用realStartActivityLocked创建目标activity。

 final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
            ...
           app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                    new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);

        ...
}

进入到ActivityThread.scheduleLaunchActivity( … );

 public final void scheduleLaunchActivity( ... ){

            ActivityClientRecord r = new ActivityClientRecord();
            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.referrer = referrer;
            r.voiceInteractor = voiceInteractor;
            r.activityInfo = info;

               ...

            r.overrideConfig = overrideConfig;
            updatePendingConfiguration(curConfig);
            sendMessage(H.LAUNCH_ACTIVITY, r);

}

封装activity的信息,并发给送LAUNCH_ACTIVITY消息。主线程消息调用handleLaunchActivity()

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();
        mSomeActivitiesChanged = true;

        if (r.profilerInfo != null) {
            mProfiler.setProfiler(r.profilerInfo);
            mProfiler.startProfiling();
        }

        // Make sure we are running with the most recent config.
        handleConfigurationChanged(null, null);

        WindowManagerGlobal.initialize();
        Activity a = performLaunchActivity(r, customIntent);
        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
                 ....
            }
        } else {
            // If there was an error, for any reason, tell the activity manager to stop us.
            try {
                ActivityManagerNative.getDefault()
                    .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
    }

通过performLaunchActivity(),创建了activity,然后马上handleResumeActivity()让activity显示出来。。我们先进入performLaunchActivity,看看activity是如何造出来的

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ...
      try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }

        ...
        activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window);
        ....
         if (r.isPersistable()) {
             mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
         } else {
             mInstrumentation.callActivityOnCreate(activity, r.state);
         }
        ...
          mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
         ...
           mInstrumentation.callActivityOnPostCreate(activity, r.state);
        ...

}
//Instrumentation.newActivity();
public Activity newActivity(ClassLoader cl, String className, Intent intent)  throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        return (Activity)cl.loadClass(className).newInstance();
    }

这里有熟悉的Instrumentation,创建application,activity都是这个类的功劳。ClassLoader类加载器实例化对象,接着走activity.attach走activity的第一个生命周期,进入activity.attach();

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,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window) {
        attachBaseContext(context);

        mFragments.attachHost(null /*parent*/);

        mWindow = new PhoneWindow(this, window);
        mWindow.setWindowControllerCallback(this);
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);
        ...
        mMainThread = aThread;
        mInstrumentation = instr; 
        mApplication = application;
         ... 
        if (voiceInteractor != null) {
            if (lastNonConfigurationInstances != null) {
                mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
            } else {
                mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
                        Looper.myLooper());
            }
        }

        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        if (mParent != null) {
            mWindow.setContainer(mParent.getWindow());
        }
        mWindowManager = mWindow.getWindowManager();
        mCurrentConfig = config;
    }

一进方法就第一个调用了attachBaseContext,在application里面也有调用这个方法。PhoneWindow是Window的子类,里面有一个DecorView,DecorView用于装包括状态栏在内的整个布局。回到performLaunchActivity(),进入callActivityOnCreate();

    public void callActivityOnCreate(Activity activity, Bundle icicle,
            PersistableBundle persistentState) {
        prePerformCreate(activity);
        activity.performCreate(icicle, persistentState);
        postPerformCreate(activity);
    }

    final void performCreate(Bundle icicle) {
        restoreHasCurrentPermissionRequest(icicle);
        onCreate(icicle);
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
    }

这里调用了Activity的onCreate(icicle);接着callActivityOnRestoreInstanceState()会调用Activity的onRestoreInstanceState(),callActivityOnPostCreate()回调用Activity的OnPostCreate()。Activity创建完毕,回到handleLaunchActivity(),进入handleResumeActivity()

  final void handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
    ...
      r = performResumeActivity(token, clearHide, reason);
    ...
          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 (r.mPreserveWindow) {
                  a.mWindowAdded = true;
                  r.mPreserveWindow = false;
                  ViewRootImpl impl = decor.getViewRootImpl();
                  if (impl != null) {
                      impl.notifyChildRebuilt();
                  }
              }
              if (a.mVisibleFromClient && !a.mWindowAdded) {
                  a.mWindowAdded = true;
                  wm.addView(decor, l);
              }
        }

    ...
}

 public final ActivityClientRecord performResumeActivity(IBinder token,
            boolean clearHide, String reason) {

           ...
            r.activity.performResume();
           ... 

}

在performResume里面调用了 mInstrumentation.callActivityOnRestart(this); mInstrumentation.callActivityOnResume(this);进而调用了activity的onRestart(),onResume();在前面onCreate()里面setContentView()里面回去创建DecorView,并将我们写的界面布局加载在DecorView里面的content view上,这个时候仅仅是将view添加在DecorView上,还没有添加在Window窗体上,这个时候在onResume方法里做处理,通过Window获取DecorView并将DecorView添加到ViewManager里,最后在设置view的VISIBLE(调用activity.makeVisible()),那么现在用户就可以看见界面了。

是时候来一段小小的总结了:

启动app最先调用
–>Activity.startActivitySafely()–>startActivity()
–>startActivityForResult() 这时候requestCode=-1, 这是默认值,所以我们不能传-1。
–> Instrumentation.execStartActivity(),Instrumentation 这个类很关键,创建application和activity都是它
–> ActivityManagerNative.getDefault().startActivity() 这里涉及到IPC,ActivityManagerNative.getDefault()就是ActivityManagerService
–>startActivityAsUser() –>ActivityStackSupervisor.startActivityMayWait(), 对intent数据进行封装
–>startActivityLocked() –>startActivityUnchecked()
–> ActivityStack.startActivityLocked() –>resumeTopActivitiesLocked()
–> ActivityStack.resumeTopActivityLocked() –>resumeTopActivityInnerLocked()
–> ActivityStackSupervisor.startSpecificActivityLocked() 判断进程是否创建,创建了进程realStartActivityLocked()启动activity,否则往下走
–> ActivityManagerService.startProcessLocked() 去创建进程 –>startProcessLocked()
–> Process.start() –>startViaZygote() 最终会在ZygoteState fork一个进程。

进程创建好了,现在进入activityThread走app的生命周期

–> 进入main() 初始化Looper,创建ActivityThread对象 –> attach()
–> ActivityManagerService.attachApplication(mAppThread), 将ApplicationThread传入AMS
–> attachApplicationLocked(),将AMS里面相关信息封装传回
–>ApplicationThread.bindApplication(),封装信息,发送消息sendMessage(H.BIND_APPLICATION, data)
–> handleBindApplication() ,实例化Instrumentation,通过Instrumentation实例化application,并调用生命周期
–> ActivityStackSupervisor.attachApplicationLocked(),获取栈定activity信息
–>realStartActivityLocked(),前面提到过,去创建activity
–>ActivityThread.scheduleLaunchActivity(),封装activity并发消息sendMessage(H.LAUNCH_ACTIVITY, r)
–>handleLaunchActivity()主线程处理ui
–>performLaunchActivity() –> mInstrumentation.newActivity()创建activity
–>Activity.attach(),第一个生命周期,创建PhoneWindow,
–>mInstrumentation.callActivityOnCreate,调用activity.OnCreate
–>handleResumeActivity() –>performResumeActivity()最终调用Activity.onResume()
–>activity.makeVisible(),DecorView设置VISIBLE

完整的app启动和activity创建过程

over

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值