美文网首页Android知识程序员Android开发
Android设计模式(四)续:Activity的onCreat

Android设计模式(四)续:Activity的onCreat

作者: 喵了个呜s | 来源:发表于2017-03-30 00:40 被阅读509次

    这里分析的是app第一次启动时的第一个Activity的onCreate()方法的启动流程。

    先贴一下大致的流程图吧,不会画,很丑


    ActivityThread.main()

    APP的启动入口应该都知道是ActivityThread的main方法了,所以整个APP的启动就从这里开始,直到我们看到首页。代码不多:

    package android.app;
    public final class ActivityThread {
        public static void main(String[] args) {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
            SamplingProfilerIntegration.start();
            CloseGuard.setEnabled(false);
            Environment.initForCurrentUser();
            EventLogger.setReporter(new EventLoggingReporter());
            final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
            TrustedCertificateStore.setDefaultUserDirectory(configDir);
            Process.setArgV0("<pre-initialized>");
            Looper.prepareMainLooper();
            ActivityThread thread = new ActivityThread();
            thread.attach(false);
            if (sMainThreadHandler == null) {
                sMainThreadHandler = thread.getHandler();
            }
            if (false) {
                Looper.myLooper().setMessageLogging(new
                        LogPrinter(Log.DEBUG, "ActivityThread"));
            }
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            Looper.loop();
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }
    }
    

    其实通过这个代码我们可以发现一个有趣的现象,APP可以一直运行不会退出就因为这个main方法最后的Looper.loop()是个死循环。

    当一个APP启动的时候,系统会从Zygone线程中为应用fork一个新的线程,然后在线程中执行ActivityThread的main方法。
    main方法中主要流程就是:

    • 准备一个主线程的Looper
    • 新建一个ActivityThread,并执行他的attach方法
    • 开启Looper的loop方法开始无限循环的读取消息队列的消息 并处理。

    ActivityThread.attach(false)

    下面看一下ActivityThread.attach(),在main()中传入的参数是FALSE,说明这个APP不是系统APP。所以我们主要就看不是系统APP的处理。

    private void attach(boolean system) {
            sCurrentActivityThread = this;
            mSystemThread = system;
            if (!system) {
    //不是系统APP
                ViewRootImpl.addFirstDrawHandler(new Runnable() {
                    @Override
                    public void run() {
    //确定虚拟机正常
                        ensureJitEnabled();
                    }
                });
              //.....略
    //获取一个ActivityManagerService  AMS
                final IActivityManager mgr = ActivityManagerNative.getDefault();
                try {
    //mAppThread = new ApplicationThread(),绑定到AMS上
                    mgr.attachApplication(mAppThread);
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
               //......略
            } else {
               //.....略
            }
    

    ActivityManagerNative.getDefault()就是获取一个AMS,从下面的代码可以看到用的是单例模式从SystemManager中获取到。

    package android.app;
    public abstract class ActivityManagerNative extends Binder implements IActivityManager{
        static public IActivityManager getDefault() {
            return gDefault.get();
        }
        private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
            protected IActivityManager create() {
    //获取AMS
                IBinder b = ServiceManager.getService("activity");
                if (false) {
                    Log.v("ActivityManager", "default service binder = " + b);
                }
                IActivityManager am = asInterface(b);
                if (false) {
                    Log.v("ActivityManager", "default service = " + am);
                }
                return am;
            }
        };
    }
    

    (AMS)mgr.attachApplication()

    package com.android.server.am;
    public final class ActivityManagerService extends ActivityManagerNative
            implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
         @Override
        public final void attachApplication(IApplicationThread thread) {
            synchronized (this) {
                int callingPid = Binder.getCallingPid();
                final long origId = Binder.clearCallingIdentity();
    //执行AMS的这个方法
                attachApplicationLocked(thread, callingPid);
                Binder.restoreCallingIdentity(origId);
            }
        }
        
        private final boolean attachApplicationLocked(IApplicationThread thread,
                int pid) {
            //......略
        
      
            try {
                          ProfilerInfo profilerInfo = profileFile == null ? null
                        : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
    //执行了ApplicationThread的bindApplication方法
                thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                        profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                        app.instrumentationUiAutomationConnection, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(mConfiguration), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked());
                //.....
            } catch (Exception e) {
               //......
            } 
            // See if the top visible activity is waiting to run in this process...
            if (normalMode) {
                try {
                    if (mStackSupervisor.attachApplicationLocked(app)) {
                        didSomething = true;
                    }
                } catch (Exception e) {
          
                }
            }
            return true;
        }
    }
    

    这里 主要看两个方法,thread.bindApplication(......)方法和mStackSupervisor.attachApplicationLocked(app)。
    ApplicationThread是ActivityThread的内部类,里面主要还是把这个ApplicationThread绑定到AMS中。
    mStackSupervisor是一个ActivityStackSupervisor类,在AMS创建的时候初始化。

    mStackSupervisor.attachApplicationLocked(app)

    下面看他的方法

    package com.android.server.am;
    public final class ActivityStackSupervisor implements DisplayListener {
        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 {
    //看这个方法就知道是真正启动一个Activity
                                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;
        }
    
        final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
                boolean andResume, boolean checkConfig) throws RemoteException {
    
    //这个传进来是true,所以一定会进去
            if (andResume) {
    //冻结尚未启动的其他APP
                r.startFreezingScreenLocked(app, 0);
                mWindowManager.setAppVisibility(r.appToken, true);
                // 搜集启动比较慢的APP的信息
                r.startLaunchTickingLocked();
            }
    
    
            final ActivityStack stack = task.stack;
            try {
                if (app.thread == null) {
                    throw new RemoteException();
                }
                List<ResultInfo> results = null;
                List<ReferrerIntent> newIntents = null;
                if (andResume) {
                    results = r.results;
                    newIntents = r.newIntents;
                }
               //...
    
                if (r.isHomeActivity()){
    //如果是桌面的activity,就加到栈底
                    mService.mHomeProcess = task.mActivities.get(0).app;
                }
               
            //。。。。
                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);
            } catch (RemoteException e) {          
                }
            }
    
            return true;
        }
    }
    

    上面的方法里一大堆代码,主要就是检查准备要启动的Activity的信息,信息正常的话就执行 app.thread.scheduleLaunchActivity(.....)方法。
    然后就又回到了ApplicationThread:

    ApplicationThread.scheduleLaunchActivity(.....)

    package android.app;
    public final class ActivityThread {
        private class ApplicationThread extends ApplicationThreadNative {
            @Override
            public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                    ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                    CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                    int procState, Bundle state, PersistableBundle persistentState,
                    List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                    boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
                updateProcessState(procState, false);
                ActivityClientRecord r = new ActivityClientRecord();
                r.token = token;
                r.ident = ident;
                r.intent = intent;
                r.referrer = referrer;
                r.voiceInteractor = voiceInteractor;
                r.activityInfo = info;
                r.compatInfo = compatInfo;
                r.state = state;
                r.persistentState = persistentState;
    
                r.pendingResults = pendingResults;
                r.pendingIntents = pendingNewIntents;
    
                r.startsNotResumed = notResumed;
                r.isForward = isForward;
    
                r.profilerInfo = profilerInfo;
    
                r.overrideConfig = overrideConfig;
                updatePendingConfiguration(curConfig);
    
                sendMessage(H.LAUNCH_ACTIVITY, r);
            } 
       }
    }
    

    里面创建了一个ActivityClientRecord来保存activity的各种信息,然后放在消息里发送给H,消息的标识是H.LAUNCH_ACTIVITY,消息的内容就是这个ActivityClientRecord。
    H也是ActivityThread的一个内部类:

    ActivityThread.H

    private class H extends Handler {
        public static final int LAUNCH_ACTIVITY         = 100;
        public void handleMessage(Message msg) {
            switch (msg.what) {
                    case LAUNCH_ACTIVITY: {
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                        final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
                        r.packageInfo = getPackageInfoNoCheck(
                                r.activityInfo.applicationInfo, r.compatInfo);
                        handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    } break;
                  }
        }
    }
    

    这个handler接收到LAUNCH_ACTIVITY的信息后,会调用handleLaunchActivity(...)方法

    ActivityThread.handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");

    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
          //.....
            Activity a = performLaunchActivity(r, customIntent);
    //.....
        }
    

    ActivityThread.performLaunchActivity(r, customIntent)

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
       //获取activity的信息
            ActivityInfo aInfo = r.activityInfo;
            //...对信息进行一些判断 略
            Activity activity = null;
            try {
    //通过反射获取到activity类
                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);
                }
            }
    
            try {
    //获取application
                Application app = r.packageInfo.makeApplication(false, mInstrumentation);
                if (activity != null) {
    //生成activity的Context
                    Context appContext = createBaseContextForActivity(r, activity);
                   //....略
    //将activity绑定到application
                    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);
                 //...略
    //调用callActivityOnCreate方法
                    if (r.isPersistable()) {
                        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                    } else {
                        mInstrumentation.callActivityOnCreate(activity, r.state);
                    }       
                }
            } catch (SuperNotCalledException e) {         
            }
            return activity;
        }
    

    继续

    Instrumentation.callActivityOnCreate

    package android.app;
    public class Instrumentation {
        public void callActivityOnCreate(Activity activity, Bundle icicle) {
            prePerformCreate(activity);
            activity.performCreate(icicle);
            postPerformCreate(activity);
        }
    }
    

    是不是终于看到了activity的方法,马上就到了

    activity.performCreate(icicle);

    package android.app;
    public class Activity extends ContextThemeWrapper
            implements LayoutInflater.Factory2,
            Window.Callback, KeyEvent.Callback,
            OnCreateContextMenuListener, ComponentCallbacks2,
            Window.OnWindowDismissedCallback, WindowControllerCallback {
        
        final void performCreate(Bundle icicle) {
            restoreHasCurrentPermissionRequest(icicle);
            onCreate(icicle);
            mActivityTransitionState.readState(icicle);
            performCreateCommon();
        }
    }
    

    看到没,执行到了onCreate方法,还有一些生命周期的方法也是这样的逻辑,包括service和广播。

    相关文章

      网友评论

        本文标题:Android设计模式(四)续:Activity的onCreat

        本文链接:https://www.haomeiwen.com/subject/gspeottx.html