码迷,mamicode.com
首页 > 其他好文 > 详细

应用启动与startActivity()入门

时间:2016-05-12 22:15:30      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:

应用的启动

        一个应用启动时,入口方法为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()

基础

        所有的startActivity()最终都会执行到下Activity#startActivityForResult

 public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
        if (mParent == null) {
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                // If this start is requesting a result, we can avoid making
                // the activity visible until the result is received.  Setting
                // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
                // activity hidden during this time, to avoid flickering.
                // This can only be done when a result is requested because
                // that guarantees we will get information back when the
                // activity is finished, no matter what happens to it.
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);
            // TODO Consider clearing/flushing other event sources and events for child windows.
        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                // Note we want to go through this method for compatibility with
                // existing applications that may have overridden it.
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }
        虽然上面通过mParent进行判断生成两部分调用,但他们殊途同归,最终都调用mInstrumentation.execStartActivity()。

        另外要记住mMainThread.getApplicationThread()返回的是一个ApplicationThread类型的对象。而sInstrumentation是一个Instrumentation的对象。

ApplicationThread#performLaunchActivity()

        上述execStartActivity()方法中有如下代码:

	int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mWho : null,
                        requestCode, 0, null, options);
    checkStartActivityResult(result, intent);//其作用主要是判断result的值,如果值代表着错误就扔个异常出去。略
再看ActivityManagerNative.getDefault().startActivity()经过百转千回,最终调用的是ApplicationThread#scheduleLaunchActivity,该方法内容又通过类名为H的handler发送了一个what为LAUNCH_ACTIVITY的msg。在该部分中又调用了handleLaunchActivity,再接着调用了performLaunchActivity。其主体代码如下:
	private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {

        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        ComponentName component = r.intent.getComponent();
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }
	//上面是获取待启动activity的信息,并组装成一个ComponentName对象。
		
        Activity activity = null;
        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);
            }
        }
	//在newActivity中,是通过反射拿到一个activity的实例对象的,这里就创建了新的activity对象。
		
        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
	   //makeApplication 反射拿application对象,如果已经存储就直接返回。并调用Application#onCreate()方法。
            //一些输出语句,略
            if (activity != null) {
                Context appContext = createBaseContextForActivity(r, activity);
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                //调用新创建的activity对象的attack()方法,主要是进行一系列的初始化工作,如创建PhoneWindow对象等
                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);
                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                activity.mStartedActivity = false;
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }

                activity.mCalled = false;
                if (r.isPersistable()) {//调用到onCreate(),只不过前者调用的是onCreate(Bundle,PersistableBundle),后者调用的是onCreate(Bundle)
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
	
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onCreate()");
                }
                r.activity = activity;
                r.stopped = true;
                if (!r.activity.mFinished) {
                    activity.performStart();//调用Activity#onStart()
                    r.stopped = false;
                }
                if (!r.activity.mFinished) {//调用onRestoreInstanceState()
                    if (r.isPersistable()) {
                        if (r.state != null || r.persistentState != null) {
                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                    r.persistentState);
                        }
                    } else if (r.state != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                    }
                }
				//由上述两个的判断顺序可以知道,onRestoreInstanceState()是在onStart()之后调用的,并且在有Bundle对象的时候才调用
                if (!r.activity.mFinished) {//调用Activity#onPostCreate()
                    activity.mCalled = false;
                    if (r.isPersistable()) {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state,
                                r.persistentState);
                    } else {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state);
                    }
                    if (!activity.mCalled) {
                        throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                            " did not call through to super.onPostCreate()");
                    }
                }
            }
            r.paused = true;

            mActivities.put(r.token, r);

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }

        return activity;
    }
        整体思考在注释中。
        在上述过程中通过createBaseContextForActivity()创建了一个Context对象,方法如下:
	
	private Context createBaseContextForActivity(ActivityClientRecord r,
            final Activity activity) {
        ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.token);
        appContext.setOuterContext(activity);
        Context baseContext = appContext;

        final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
        try {
            final int displayId = ActivityManagerNative.getDefault().getActivityDisplayId(r.token);
            if (displayId > Display.DEFAULT_DISPLAY) {
                Display display = dm.getRealDisplay(displayId, r.token);
                baseContext = appContext.createDisplayContext(display);//也是直接new一个ContextImpl对象返回的
            }
        } catch (RemoteException e) {
        }

        // For debugging purposes, if the activity's package name contains the value of
        // the "debug.use-second-display" system property as a substring, then show
        // its content on a secondary display if there is one.
        String pkgName = SystemProperties.get("debug.second-display.pkg");
        if (pkgName != null && !pkgName.isEmpty()
                && r.packageInfo.mPackageName.contains(pkgName)) {
            for (int displayId : dm.getDisplayIds()) {
                if (displayId != Display.DEFAULT_DISPLAY) {
                    Display display = dm.getRealDisplay(displayId, r.token);
                    baseContext = appContext.createDisplayContext(display);
                    break;
                }
            }
        }
        return baseContext;
    }

        我们可以发现在整个过程中,baseContext都是ContextImpl类型的。而该对象会传递到Activity#attach()中,并且最终被赋值到ContextWrapper#mBase(Activity也是间接继承于ContextWrapper)属性。

总结

        1,由上面的整个过程可以发现,在activity整个启动过程中最重要的两个类是ActivityThread(关键是其内部类ApplicationThread)与Instrumentation。
        2,Activity中涉及到的Context都是ContextImpl对象。常用的startService(),stopService(),registerReceiver(),unregisterReceiver(),sendBroadcast()getAssets(),getResource(),bindService(),unbindService()
与getContentResolver()等都是直接调用ContextImpl中的方法的。


应用启动与startActivity()入门

标签:

原文地址:http://blog.csdn.net/u010410408/article/details/51352403

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!