android 深入activity

来源:互联网 发布:linux cp拷贝多个文件 编辑:程序博客网 时间:2024/06/05 14:10

相关类简介

一、ActivityManagerService 简称AMS,是Android内核的核心功能之一,在系统启动SystemServer时启动此服务。
AMS提供的功能主要包括以下几个方面:
1。对于Android四大组件(activity service broadcast content provider)的管理,包括启动,生命周期管理等
2.进程OOM adj以级LRU weight管理
AMS主要代码位于:frameworks\base\services\java\com\android\server\am下

二、ActivityThread 不是一个线程类,主线程调用其main方法。
main方法中关键处:

Looper.prepareMainLooper();        ActivityThread thread = new ActivityThread();        thread.attach(false);        if (sMainThreadHandler == null) {            sMainThreadHandler = thread.getHandler();        }        AsyncTask.init();        if (false) {            Looper.myLooper().setMessageLogging(new                    LogPrinter(Log.DEBUG, "ActivityThread"));        }        Looper.loop();

由上代码可知ActivityThread处理消息。

三、ActivityManagerNative:服务中枢,ActivityManagerNative继承自Binder并实现IActivityManager,它提供了服务接口和Binder接口的相互转化功能,并在内部存储服务代理对像,并提供了getDefault方法返回服务代理

四、ActivityManagerProxy:服务代理,由ActivityManagerProxy实现,用于与Server端提供的系统服务进行进程间通信

ApplicationThread

客户端将其传送给AMS,AMS通过它与客户端通信。在这里ApplicationThread是aidl中的服务端,AMS则成为了客户端。区别客户端服务端就在与哪方调用了asInterface方法。

ActivityClientRecord

activity状态信息记录的一个描述类

ActivityRecord

AMS记录activity的信息

Context

上下文,封装公共的操作,如获取资源

Instrumentation

负责打开activity各种生命周期方法。作用:application的创建,生命周期的管理,启动activity

由浅入深进行分析

在activity的onCreate中抛异常,可得到如下log
执行顺序由错误可看到
打开一个应用,则会启动一个应用进程,然后创建一个主线程,之后调用ActivityThread的main方法。
main方法关键代码

         Looper.prepareMainLooper();//一个主线程的looper对象        ActivityThread thread = new ActivityThread();        thread.attach(false);        if (sMainThreadHandler == null) {            sMainThreadHandler = thread.getHandler();        }        AsyncTask.init();        if (false) {            Looper.myLooper().setMessageLogging(new                    LogPrinter(Log.DEBUG, "ActivityThread"));        }        Looper.loop();

thread.attach(false)中关键代码:

//ActivityManagerNative的getDefault方法,可以得到一个ActivityManagerProxy对像的引用,进而通过该代理对像调用远程服务AMS的方法,也就是说应用通过ActivityManagerProxy与AMS通信。IActivityManager mgr = ActivityManagerNative.getDefault();            try {            //这里mAppThread为ApplicationThread,将启动的应用的mAppThread传附加到AMS,AMS通过获取mAppThread这个IBinder的代理与应用通信。其原理就是AIDL                mgr.attachApplication(mAppThread);            } catch (RemoteException ex) {                // Ignore            }

对于孰知AIDL的同学,肯定知道,其上attachApplication方法是被代理对象调用。查看代理对象ActivityManagerProxy的attachApplication方法,发现其关键一行mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
在AIDL中,ActivityManagerProxy为服务端ActivityManagerNative的代理对象,接着产看ActivityManagerNative的onTransact方法中有该ATTACH_APPLICATION_TRANSACTION对应的地方,代码如下:

case ATTACH_APPLICATION_TRANSACTION: {            data.enforceInterface(IActivityManager.descriptor);            IApplicationThread app = ApplicationThreadNative.asInterface(                    data.readStrongBinder());            if (app != null) {                attachApplication(app);            }            reply.writeNoException();            return true;        }

这里获取ApplicationThreadNative的代理对象,然后将该代理对象附加到AMS。AMS继承自ActivityManagerNative。AMS的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);        }    }

继续看attachApplicationLocked方法,其中有这么一行代码:

thread.bindApplication(processName, appInfo, providers,                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,                    app.instrumentationArguments, app.instrumentationWatcher,                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,                    isRestrictedBackupMode || !normalMode, app.persistent,                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),                    mCoreSettingsObserver.getCoreSettingsLocked());

thread为ApplicationThread的代理类,调用了代理类的bindApplication方法。ApplicationThread的bindApplication被调用,其实ApplicationThread继承自ApplicationThreadNative。
ApplicationThread的bindApplication方法:

public final void bindApplication(String processName,                ApplicationInfo appInfo, List<ProviderInfo> providers,                ComponentName instrumentationName, String profileFile,                ParcelFileDescriptor profileFd, boolean autoStopProfiler,                Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,                IUiAutomationConnection instrumentationUiConnection, int debugMode,                boolean enableOpenGlTrace, 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.enableOpenGlTrace = enableOpenGlTrace;            data.restrictedBackupMode = isRestrictedBackupMode;            data.persistent = persistent;            data.config = config;            data.compatInfo = compatInfo;            data.initProfileFile = profileFile;            data.initProfileFd = profileFd;            data.initAutoStopProfiler = false;            queueOrSendMessage(H.BIND_APPLICATION, data);        }

这里发了一个消息给H,再通过H处理消息,执行ActivityThread的handleBindApplication方法。

startActivity过程

startActivity启动过程分析,这篇文章分析很详细了。
我这里简单说下,有了之前的分析,我们已经知道了应用与AMS的通信过程,通过ActivityManagerNative获取AMS的代理对象,并执行代理对象的startActivity方法,ActivityManagerNative的onTransact
处理代理端发的请求,执行START_ACTIVITY_TRANSACTION这个case。中间经历一段处理过程,然后看ASS.realStartActivityLocked这个方法,ASS是ActivityStackSupervisor。其中关键一句

app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,                System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),                new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,                task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,                newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);

执行了ApplicationThreadProxy的scheduleLaunchActivity方法。该代理transact一个SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION,查看
ApplicationThreadNative的onTransact中的SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION的case。执行了ActivityThread的scheduleLaunchActivity方法。然后发了一个消息给H
也就是这句queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
H中相应case的地方:

case LAUNCH_ACTIVITY: {                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;                    r.packageInfo = getPackageInfoNoCheck(                            r.activityInfo.applicationInfo, r.compatInfo);                    handleLaunchActivity(r, null);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                } break;

执行了ActivityThread的handleLaunchActivity方法。查看H中其他case,可以找到activity相应生命周期对应的消息(如PAUSE_ACTIVITY)。接着看上面,handleLaunchActivity中执行了performLaunchActivity方法,performLaunchActivity中关键代码:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {       .......省略        Activity activity = null;        try {            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();            //通过Instrumentation.newActivity创建activity            activity = mInstrumentation.newActivity(                    cl, component.getClassName(), r.intent);            StrictMode.incrementExpectedActivityCount(activity.getClass());            r.intent.setExtrasClassLoader(cl);            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 (localLOGV) Slog.v(TAG, "Performing launch of " + r);            if (localLOGV) Slog.v(                    TAG, r + ": app=" + app                    + ", appName=" + app.getPackageName()                    + ", pkg=" + r.packageInfo.getPackageName()                    + ", comp=" + r.intent.getComponent().toShortString()                    + ", dir=" + r.packageInfo.getAppDir());            if (activity != null) {            //createBaseContextForActivity中activity与Context相互关联                Context appContext = createBaseContextForActivity(r, activity);                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());                Configuration config = new Configuration(mCompatConfiguration);                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "                        + r.activityInfo.name + " with config " + config);                //activity与windowi关联                activity.attach(appContext, this, getInstrumentation(), r.token,                        r.ident, app, r.intent, r.activityInfo, title, r.parent,                        r.embeddedID, r.lastNonConfigurationInstances, config);                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; //生命周期onCreate调用               mInstrumentation.callActivityOnCreate(activity, r.state);                ....省略        } 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;    }

通过Instrumentation.newActivity创建activity,其方法:

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

就是通过ClassLoader来newInstance。接着看performLaunchActivity中Application的创建:

public Application makeApplication(boolean forceDefaultAppClass,            Instrumentation instrumentation) {        if (mApplication != null) {            return mApplication;        }        Application app = null;        String appClass = mApplicationInfo.className;        if (forceDefaultAppClass || (appClass == null)) {            appClass = "android.app.Application";        }        try {            java.lang.ClassLoader cl = getClassLoader();            ContextImpl appContext = new ContextImpl();            appContext.init(this, null, mActivityThread);            //这里创建Application            app = mActivityThread.mInstrumentation.newApplication(                    cl, appClass, appContext);            appContext.setOuterContext(app);            //从这代码块可看出ContextImpl与Application相互关联(Application关联ContextImpl在mInstrumentation.newApplication中可看到,其实Activity也一样的,后面会看到)        } 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) {            try { //Application生命周期调用,也就是onCreate               instrumentation.callApplicationOnCreate(app);            } catch (Exception e) {                if (!instrumentation.onException(app, e)) {                    throw new RuntimeException(                        "Unable to create application " + app.getClass().getName()                        + ": " + e.toString(), e);                }            }        }        return app;    }

回到performLaunchActivity方法中,看

activity.attach(appContext, this, getInstrumentation(), r.token,                        r.ident, app, r.intent, r.activityInfo, title, r.parent,                        r.embeddedID, r.lastNonConfigurationInstances, config);

attach方法代码:

mWindow = PolicyManager.makeNewWindow(this);//mWindow设置按键事件回调,this是activity,底层处理完一系列物理按键时间后到应用层这边,activity的dispatch系列方法回调。如Activity的dispatchKeyEvent起到拦截按键作用,如果这一步不处理,将分发DecorView处理。        mWindow.setCallback(this);        mWindow.getLayoutInflater().setPrivateFactory(this);        if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {            mWindow.setSoftInputMode(info.softInputMode);        }        if (info.uiOptions != 0) {            mWindow.setUiOptions(info.uiOptions);        }        mUiThread = Thread.currentThread();        mMainThread = aThread;        mInstrumentation = instr;        mToken = token;        mIdent = ident;        mApplication = application;        mIntent = intent;        mComponent = intent.getComponent();        mActivityInfo = info;        mTitle = title;        mParent = parent;        mEmbeddedID = id;

mWindow = PolicyManager.makeNewWindow(this)创建了一个PhoneWindow。之后执行mInstrumentation.callActivityOnCreate(activity, r.state),activity的onCreate会执行,我们一般会写setContentView方法

public void setContentView(int layoutResID) {        //window就是之前所创建        getWindow().setContentView(layoutResID);        initActionBar();    }

PhoneWindow的

 @Override    public void setContentView(int layoutResID) {        if (mContentParent == null) {        //创建decoreview,生成并设置整个布局            installDecor();        } else {            mContentParent.removeAllViews();        }        mLayoutInflater.inflate(layoutResID, mContentParent);        final Callback cb = getCallback();        if (cb != null && !isDestroyed()) {            cb.onContentChanged();        }    }

activity的onResume分析

final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,            boolean reallyResume) {            ...省略            //这句间接执行了activity的onResume            ActivityClientRecord r = performResumeActivity(token, clearHide);            ...省略            //下面windowmanager添加window,windowmanager在activity的attach方法中创建赋值的。            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 (a.mVisibleFromClient) {                    a.mWindowAdded = true;                    //真实添加操作是WindowManagerImpl中的WindowManagerGlobal,而WindowManagerGlobal是使用ViewRootImpl做具体的操作                    wm.addView(decor, l);                }       }       ...省略       //界面真实可见了        if (r.activity.mVisibleFromClient) {                    r.activity.makeVisible();                }}

值得注意的是,窗口真实添加操作是WindowManagerImpl中的WindowManagerGlobal,而WindowManagerGlobal是使用ViewRootImpl做具体的操作。

private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();

mGlobal 是单例。

WindowManagerGlobal的addView方法与ViewRootImpl相关的地方:

...root = new ViewRootImpl(view.getContext(), display);...root.setView(view, wparams, panelParentView);...

ViewRootImpl的setView方法中有句view.assignParent(this),这句就是将DecorView的parent赋值为ViewRootImpl。如果调用view的
invalidate,会一层一层往上调用,最后调用ViewRootImpl的invalidateChildInParent方法。其中会执行checkThread方法,这方法会判断是否是主线程更新ui。

参考

startActivity启动过程分析

源码