ActivityThead 启动页面分析

ActivityThead 路径之前的回忆

  • 上一篇文章我们分析了应用是如何从左面点击 到启动ActivityThread 的main方法的,简单的流程如下
    • 点击图标 -->进入Activity 的startActivity()方法,而这个方法最终交给了 Intrumentation ,再交给ActivityManagerService(我们看到的是IActivityManager ActivityManagerService是其具体的实现类),再交给ActivityStack(高版本中叫做ActivityStarter),在这里面进行了判断,如果当前进程不存在,那么我们首先会去创建一个应用的进程, 交给了额Zygote以及ZygoteInit类进行处理,他们内部则是开启了服务端的socket用来进行通信,并启动SystemServer,最终会走到RuntimeInit中,从这个了类中利用反射的形式开启了ActivityThread 的main方法。其中zygote主要机型一些资源的资源的加载,而SystemServer 则是开启了祥光的各种Service。上半部分就回忆到这里。

ActivityThread 的main方法

不多说上代码

// 本文依旧基于API_15,main方法就这么简单,几行代码
 public static void main(String[] args) {
        SamplingProfilerIntegration.start();
        CloseGuard.setEnabled(false);
        Process.setArgV0("<pre-initialized>");
        //整个应用的的UI线程的线程looper  也就是mainlooper启动
        Looper.prepareMainLooper();
        if (sMainThreadHandler == null) {
            sMainThreadHandler = new Handler();
        }
        //创建了一个ActivitThread并和当前的应用进行绑定,其中包含了我们Applciation的创建,接下来我们逐步来看
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        Looper.loop();
    }

我们进入到attach方法进行查看,到底都干了啥!

 private void attach(boolean system) {
        sThreadLocal.set(this);
        mSystemThread = system;
        if (!system) {
            ViewRootImpl.addFirstDrawHandler(new Runnable() {
                public void run() {
                    ensureJitEnabled();
                }
            });
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>");
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            //ActivityManagerService和ApplicationThread(这个类我们后面会讲,但我们要知道他是为了ActivityThread和ActivityManagerService同行的通道,原理还是IPC机制)进行绑定,
            IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                // Ignore
            }
        } else {
            android.ddm.DdmHandleAppName.setAppName("system_process");
            try {
                mInstrumentation = new Instrumentation();
                ContextImpl context = new ContextImpl();
                context.init(getSystemContext().mPackageInfo, null, this);
                **//我们看到了什么 Application这个我们最熟悉不过了,这里Instrumentation会利用反射的方式进行创建,**
                Application app = Instrumentation.newApplication(Application.class, context);
                mAllApplications.add(app);
                mInitialApplication = app;
                app.onCreate(); 
            } catch (Exception e) {
                throw new RuntimeException(
                        "Unable to instantiate Application():" + e.toString(), e);
            }
        }

最让我们关注还是ActivityManagerService 的attachApplication(mAppThread); 我们看看他又做了什么操作

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

  thread.bindApplication(processName, appInfo, providers,
                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
                    app.instrumentationArguments, app.instrumentationWatcher, testMode, 
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
                    mCoreSettingsObserver.getCoreSettingsLocked());
 if (hr != null && normalMode) {
            if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
                    && processName.equals(hr.processName)) {
                try {
                //这里调用ActivityStack 的realStartActivityLocked  正式开启页面,
                    if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
                        didSomething = true;
                    }
                } catch (Exception e) {
               }
            } else {
                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
            }
        }

  ...
// 这个操作里面主要是这个方法,那我们需要弄明白 IApplicationThread  以及 bindApplication ()做了那些操作。

IApplicationThread

这里我就直接说了,IApplicationThread 其实就是一个接口,那我们最重要的是看他在那里实现的,ActivityThread类中有这么两个关乎生命周期的类 如下

  • class ApplicationThread extends ApplicationThreadNative
  • class ApplicationThreadNative extends Binder implements IApplicationThread
  • class H extends Handler

我们跟着上面的方法进入到 ApplicationThread

 public 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 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.restrictedBackupMode = isRestrictedBackupMode;
            data.persistent = persistent;
            data.config = config;
            data.compatInfo = compatInfo;
            data.initProfileFile = profileFile;
            data.initProfileFd = profileFd;
            data.initAutoStopProfiler = false;
            // 最终走到了H
            queueOrSendMessage(H.BIND_APPLICATION, data);
        }

private void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
        synchronized (this) {
            Message msg = Message.obtain();
            msg.what = what;
            msg.obj = obj;
            msg.arg1 = arg1;
            msg.arg2 = arg2;
            mH.sendMessage(msg);
        }
    }

看到这里我们大致可以认为bindApplication 进过了ApplicationThreadNative 以及ApplicationThreadProxy 进入到H 的handleMessage中

 case BIND_APPLICATION:
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);

进入方法

 private void handleBindApplication(AppBindData data) {
        mBoundApplication = data;
        mConfiguration = new Configuration(data.config);
        mCompatConfiguration = new Configuration(data.config);

        mProfiler = new Profiler();
        mProfiler.profileFile = data.initProfileFile;
        mProfiler.profileFd = data.initProfileFd;
        mProfiler.autoStopProfiler = data.initAutoStopProfiler;
        Process.setArgV0(data.processName);
        android.ddm.DdmHandleAppName.setAppName(data.processName);

        if (data.persistent) {
            Display display = WindowManagerImpl.getDefault().getDefaultDisplay();
            if (!ActivityManager.isHighEndGfx(display)) {
                HardwareRenderer.disable(false);
            }
        }
        
        if (mProfiler.profileFd != null) {
            mProfiler.startProfiling();
        }
        if (data.appInfo.targetSdkVersion <= 12) {
            AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        }
        TimeZone.setDefault(null);

   
        Locale.setDefault(data.config.locale);

 
        applyConfigurationToResourcesLocked(data.config, data.compatInfo);
        applyCompatConfiguration();

        data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);

        setupGraphicsSupport(data.info);
        if ((data.appInfo.flags &
             (ApplicationInfo.FLAG_SYSTEM |
              ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
            StrictMode.conditionallyEnableDebugLogging();
        }
        if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
                == 0) {
            Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
        }
        IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
        if (b != null) {
            IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
            try {
                ProxyProperties proxyProperties = service.getProxy();
                Proxy.setHttpProxySystemProperty(proxyProperties);
            } catch (RemoteException e) {}
        }

        if (data.instrumentationName != null) {
            ContextImpl appContext = new ContextImpl();
            appContext.init(data.info, null, this);
            InstrumentationInfo ii = null;
            try {
                ii = appContext.getPackageManager().
                    getInstrumentationInfo(data.instrumentationName, 0);
            } catch (PackageManager.NameNotFoundException e) {
            }
            if (ii == null) {
                throw new RuntimeException(
                    "Unable to find instrumentation info for: "
                    + data.instrumentationName);
            }

            mInstrumentationAppDir = ii.sourceDir;
            mInstrumentationAppPackage = ii.packageName;
            mInstrumentedAppDir = data.info.getAppDir();

            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);
		//一下一大堆都是获取mInstrumentation 的操作
            try {
                java.lang.ClassLoader cl = instrContext.getClassLoader();
                mInstrumentation = (Instrumentation)
                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
            } catch (Exception e) {
                throw new RuntimeException(
                    "Unable to instantiate instrumentation "
                    + data.instrumentationName + ": " + e.toString(), e);
            }

            mInstrumentation.init(this, instrContext, appContext,
                    new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher);
            try {
                mInstrumentation.onCreate(data.instrumentationArgs);
            }
          
        } else {
            mInstrumentation = new Instrumentation();
        }
        Application app = data.info.makeApplication(data.restrictedBackupMode, null);
        mInitialApplication = app;
       ...
        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);
            }
        }
    }

public void callApplicationOnCreate(Application app) {
        app.onCreate();
    }

一堆代码对我们而言重要的就那么几句,看最后callApplicationOnCreate 这里才正式进入了Application的onCreate回调当中,也就是应用入口,我们看到这还没有达到最初的目的,我们要看到Activity是如何创建的啊,现在呢只是看到了Application的创建。 上面提到了 进入到 ActivityStack的realStartActivityLocked方法正式开启Activity,那看看他做了什么

ActivityStack 的 realStartActivityLocked

 final boolean realStartActivityLocked(ActivityRecord r,
            ProcessRecord app, boolean andResume, boolean checkConfig)
            throws RemoteException {

       。。。
            //重要的在这里,这里的app.thread 当然是ApplicationThread     scheduleLaunchActivity
            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);
      。。。
 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);
		又是进入到 H的HandleMessage,那么我们很清楚了, H 最大的作用就是消息处理中心,所有的生命周期都在这里进行分发
            queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
        }
case LAUNCH_ACTIVITY: {
                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;

                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null);
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
 
        unscheduleGcIdler();

        if (r.profileFd != null) {
            mProfiler.setProfiler(r.profileFile, r.profileFd);
            mProfiler.startProfiling();
            mProfiler.autoStopProfiler = r.autoStopProfiler;
        }
        handleConfigurationChanged(null, null);
        //我们以前常说的Activity的绘制流程是从这个方法开始的,现在我们看到真面目了,下来的东西已经不属于这里了,ActivityManagerService 于ViewRootImpl 绘制页面了,下节再说了。
        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            Bundle oldState = r.state;
            handleResumeActivity(r.token, false, r.isForward);

            if (!r.activity.mFinished && r.startsNotResumed) {
                try {
                    r.activity.mCalled = false;
                    mInstrumentation.callActivityOnPause(r.activity);
              
                    r.state = oldState;
                    if (!r.activity.mCalled) {
                        throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                            " did not call through to super.onPause()");
                    }

                } 
                r.paused = true;
            }
        } 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);
            } catch (RemoteException ex) {
                // Ignore
            }
        }
    }
  • 到了这里我们已经很清楚了如何开启的Application以及如何开启的页面,来张图作为总结,请原谅我用的别人的。
    在这里插入图片描述
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值