应用启动

应用的启动

        一个应用启动时,入口方法为ActivityThread.main(),要注意ActivityThread只是一个普通的类,并不是继承于Thread也不是实现了Runnable。如下:

    public static void main(String[] args) {
        //略一部分代码
<span style="white-space:pre">	</span>//启动主线程中的Looper
        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);//调用attach方法

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();//返回一个H对象。H是一个Handler。
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }
        Looper.loop();//主线程开始loop
<span style="white-space:pre">	</span>//loop()是阻塞式的,如果执行到这步,就意味着程序挂了
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
        因此,该方法分两部分:第一部分调用attach(),第二部分启动主线程的Looper。
        由于调用attach()时传入的是false,所以只看其中的一部分即可:
if (!system) {//system就是attach()的参数
            ViewRootImpl.addFirstDrawHandler(new Runnable() {
                @Override
                public void run() {
                    ensureJitEnabled();
                }
            });
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                    UserHandle.myUserId());
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManagerNative.getDefault();//getDefault()调用的是gDefault.get()
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                // Ignore
            }
            // Watch for getting close to heap limit.
            BinderInternal.addGcWatcher(new Runnable() {
                @Override public void run() {
                    if (!mSomeActivitiesChanged) {
                        return;
                    }
                    Runtime runtime = Runtime.getRuntime();
                    long dalvikMax = runtime.maxMemory();
                    long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
                    if (dalvikUsed > ((3*dalvikMax)/4)) {
                        if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
                                + " total=" + (runtime.totalMemory()/1024)
                                + " used=" + (dalvikUsed/1024));
                        mSomeActivitiesChanged = false;
                        try {
                            mgr.releaseSomeActivities(mAppThread);
                        } catch (RemoteException e) {
                        }
                    }
                }
            });
        } 
gDefault()的定义如下:
    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);//远程服务返回的IBinder对象
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };
        从中可以看出gDefault.get()返回的是一个远程的IActivityManager对象。这个接口的实现类为ActivityManagerService

        因此,可以看出在attach()中拿到的mgr对象是远程的ActivityManagerService对象。然后又调用了它的attachApplication(),并将一个ApplicationThread对象(即mAppThread)当作参数传递进去了。

        而ApplicationThread继承于ApplicationThreadNative,后者又继承了Binder并实现了IApplicationThread,而IApplicationThread又继承了IInterface。因此ApplicationThread是可以进行IPC的。

        通过attach()将ApplicationThread对象传递到ActivityManagerService(简称AMS)对象中的,AMS就可以通过它和ApplicationThread进行IPC了。

        而ApplicationThread内部的大部分方法基本上都调用ActivityThread#sendMessage(),如下:

    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        if (DEBUG_MESSAGES) Slog.v(
            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
            + ": " + arg1 + " / " + obj);
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);//mH为一个Handler对象
    }
        从中可以看出,通过Handler将AMS中调用的方法(IPC是被调方执行在Binder池中,不是执行在主线程中)切换到了ActivityThread所在的线程(即主线程)中执行。

        上面就是AMS与UI线程通信的机制:通过ApplicationThread进行中转,再通过Handler转发到ActivityThread所在的线程中执行

        在AMS的attach()中,又会调用ApplicationThread#bindApplication(),最终会调用到ActivityThread#handleBindApplication(),而在该方法中如下一句代码:

            Application app = data.info.makeApplication(data.restrictedBackupMode, null);

其中data.info是LoadedApk对象,在该LoadedApk#makeApplication()中会建立Application对象。其代码如下:

public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {//已有有application对象,直接返回
            return mApplication;
        }

        Application app = null;

        String appClass = mApplicationInfo.className;
        if (forceDefaultAppClass || (appClass == null)) {//没有配置,加载系统的Application
            appClass = "android.app.Application";
        }

        try {
            java.lang.ClassLoader cl = getClassLoader();
            if (!mPackageName.equals("android")) {
                initializeJavaContextClassLoader();
            }
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);//创建Application
            appContext.setOuterContext(app);
        } catch (Exception e) {
            if (!mActivityThread.mInstrumentation.onException(app, e)) {
                throw new RuntimeException(
                    "Unable to instantiate application " + appClass
                    + ": " + e.toString(), e);
            }
        }
        mActivityThread.mAllApplications.add(app);
        mApplication = app;

        if (instrumentation != null) {//在调用该方法是,传入的是null,所以判断不会执行
            try {
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                if (!instrumentation.onException(app, e)) {
                    throw new RuntimeException(
                        "Unable to create application " + app.getClass().getName()
                        + ": " + e.toString(), e);
                }
            }
        }

        // Rewrite the R 'constants' for all library apks.
        SparseArray<String> packageIdentifiers = getAssets(mActivityThread)
                .getAssignedPackageIdentifiers();
        final int N = packageIdentifiers.size();
        for (int i = 0; i < N; i++) {
            final int id = packageIdentifiers.keyAt(i);
            if (id == 0x01 || id == 0x7f) {
                continue;
            }

            rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
        }

        return app;//返回新创建的Application对象
    }

        从上面可以看出创建完Application对象后,并没有立即调用Application#onCreate(),handleBindApplication()后继代码为:

           if (!data.restrictedBackupMode) {
                List<ProviderInfo> providers = data.providers;
                if (providers != null) {//安装ContentProvider
                    installContentProviders(app, providers);
                    mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
                }
            }
//略一部分代码
            try {
                mInstrumentation.callApplicationOnCreate(app);//才调用Application#onCreate()
            } catch (Exception e) {
                if (!mInstrumentation.onException(app, e)) {
                    throw new RuntimeException(
                        "Unable to create application " + app.getClass().getName()
                        + ": " + e.toString(), e);
                }
            }

        这上面可以看出,Application#onCreate()是会晚于ContentProvider#onCreate()



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值