美文网首页
从Android app说起

从Android app说起

作者: 老码w | 来源:发表于2019-12-06 18:12 被阅读0次

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
    本文链接:https://www.jianshu.com/p/76f94c6452c0
    先抛几个问题
    1:什么是Activity,它的作用是什么,我们一个android app看到的界面真的是Activity吗,如果不是,那是什么。
    2:我们经常看到的Context,到处都是Context,服务都是通过它获取的,它和Activity是什么关系。
    3:看到的一些文章和帖子总是会说一个Activity会对应一个PhoneWindow,那什么又是PhoneWindow,Activity和PhoneWindow的关系又是什么。
    4:我们在自定义的Activity,比如MainActivity的setContentView中设置了xml,最后就是我们看到的视图,那么它和PhoneWindow和Activity又有什么关系。
    5:有View和ViewGroup我们可以理解,但是有时候又会看到一个ViewRootImpl和DecorView。它们又是什么关系,和Activity又是什么关系。
    6:Activity,Context,Application,DecorView,PhoneWindow,ActivityThread,以及ActivityManagerService,WindowsManagerService它们是如何构建一个简单的helloworld android应用的。Application和Activity是谁先创建的,android应用中为什么我们又不用继承Application写一个MyApplication类。而如果写了,它又有什么用。

    先说一个场景,当我们点击手机桌面第一次运行app的时候,Activity是如何启动的。这个过程要说清楚其实还是比较复杂的,本篇中我们先跳跃式的从main函数开始运行说起。main函数在ActivityThread类中,如下:

    创建Activity或者说创建View

    
    public static void main(String[] args) {
           Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
           SamplingProfilerIntegration.start();
    
           // CloseGuard defaults to true and can be quite spammy.  We
           // disable it here, but selectively enable it later (via
           // StrictMode) on debug builds, but using DropBox, not logs.
           CloseGuard.setEnabled(false);
    
           Environment.initForCurrentUser();
    
           // Set the reporter for event logging in libcore
           EventLogger.setReporter(new EventLoggingReporter());
    
           // Make sure TrustedCertificateStore looks in the right place for CA certificates
           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"));
           }
    
           // End of event ActivityThreadMain.
           Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
           Looper.loop();
    
           throw new RuntimeException("Main thread loop unexpectedly exited");
       }
    
    

    main函数中创建了Looper(关于Looper和Handler和Message在后续讲)和ActivityThread,并且调用attach函数和ActivityManagerService关联起来,为什么需要和ActivityManagerService关联,因为我们知道Activity何时创建,管理都是ActivityManagerService管理的,所以就需要告诉ActivityManagerService我现在已经运行了main函数,以后有什么需要任务你就需要告诉我,而ActivityManagerService是怎么和应用通信呢,这就需要注意到attach中的这段代码

    private void attach(boolean system) {
            sCurrentActivityThread = this;
            mSystemThread = system;
            if (!system) {
                final IActivityManager mgr = ActivityManagerNative.getDefault();
                try {
                    mgr.attachApplication(mAppThread);
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
    }
    

    mgr.attachApplication(mAppThread),mgr是ActivityManagerService的client代理mAppThread是一个Binder对象。

    final ApplicationThread mAppThread = new ApplicationThread();
    
    private class ApplicationThread extends ApplicationThreadNative {
    // we use token to identify this activity without having to send the
            // activity itself back to the activity manager. (matters more with ipc)
            @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();
                updatePendingConfiguration(curConfig);
    
                sendMessage(H.LAUNCH_ACTIVITY, r);
            }
    }
    

    现在我们知道了,ActivityManagerService持有应用的mAppThread对象,通过mAppThread服务端可以告应用进行启动Activity和其它的一些操作,比方说调用scheduleLaunchActivity启动Activity。ActivityThread中有一个H类,它继承Handler,ActivityManagerService调用应用的操作最终通过H类发送消息,从Binder线程转换到应用进程的主线程进程完成。

    private class H extends Handler {
            public static final int LAUNCH_ACTIVITY         = 100;
    }
    
    public void handleMessage(Message msg) {
                if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
                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;
    }
    
    

    handleLaunchActivity中有一个performLaunchActivity调用,它会创建Activity(也就是new一个Activity),我们常常在Activity的onCreate函数中做一些初始化操作,到时我们好像很少写Activity的构造函数,比如我们的MainActivity,我们其实也是可以写它的构造函数,并且可也在里面完成一些操作,只是很少这样做罢了。至此我们终于知道了Activity的创建了。

    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
            // If we are getting ready to gc after going to the background, well
            // we are back active so skip it.
            unscheduleGcIdler();
            mSomeActivitiesChanged = true;
    
            if (r.profilerInfo != null) {
                mProfiler.setProfiler(r.profilerInfo);
                mProfiler.startProfiling();
            }
    
            // Make sure we are running with the most recent config.
            handleConfigurationChanged(null, null);
    
            if (localLOGV) Slog.v(
                TAG, "Handling launch of " + r);
    
            // Initialize before creating the activity
            WindowManagerGlobal.initialize();
    
            Activity a = performLaunchActivity(r, customIntent);
    }
    

    performLaunchActivity比较长,我们截取部分关键代码分析。part1:通过mInstrumentation的newActivity调用new出来我们的Activity,part2:创建了Activity之后会创建应用的运行Application上下文,然后调用关键的attach函数

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    //part1,通过mInstrumentation的newActivity调用new出来我们的Activity
    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);
                }
            }
    //part2,创建了Activity之后会创建应用的运行Application上下文,然后调用关键的attach函数
    try {
                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) {
                    Context appContext = createBaseContextForActivity(r, activity);
                    CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                    Configuration config = new Configuration(mCompatConfiguration);
                    if (r.overrideConfig != null) {
                        config.updateFrom(r.overrideConfig);
                    }
                    if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                            + r.activityInfo.name + " with config " + config);
                    Window window = null;
                    if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                        window = r.mPendingRemoveWindow;
                        r.mPendingRemoveWindow = null;
                        r.mPendingRemoveWindowManager = null;
                    }
                    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);
    
    //part3,创建了Activity和attach之后,就调用到了我们熟悉的Activity的OnCreate
                    activity.mCalled = false;
                    if (r.isPersistable()) {
                        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                    } else {
                        mInstrumentation.callActivityOnCreate(activity, r.state);
                    }
            }
    }
    

    创建了Activity之后,在part2中会顺带着获取到Application的对象,代表着我们应用的Application上下文,如果没有,就会创建。packageInfo是一个LoadedApk对象

    public Application makeApplication(boolean forceDefaultAppClass,
                Instrumentation instrumentation) {
            if (mApplication != null) {
                return mApplication;
            }
    Application app = null;
            try {
                ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
                app = mActivityThread.mInstrumentation.newApplication(
                        cl, appClass, appContext);
                appContext.setOuterContext(app);
            }
    
    if (instrumentation != null) {
                try {
                    instrumentation.callApplicationOnCreate(app);//会调用Application的onCreate函数
                } catch (Exception e) {
                }
            }
    

    至此我们明白了Application的创建和它的onCreate函数的调用过程。回调part2中的Activity的attach函数中来,它有一个参数就是Application。

    final void attach(Context context, ActivityThread aThread,
                Instrumentation instr, IBinder token, int ident,
                Application application, Intent intent, ActivityInfo info,
                CharSequence title, Activity parent, String id,
                NonConfigurationInstances lastNonConfigurationInstances,
                Configuration config, String referrer, IVoiceInteractor voiceInteractor,
                Window window) {
            attachBaseContext(context);
    
            mFragments.attachHost(null /*parent*/);
    
            mWindow = new PhoneWindow(this, window);
            mWindow.setWindowControllerCallback(this);
            mWindow.setCallback(this);
            .
            .  
    }
    

    终于看到PhoneWindow了,它就是在Activity的attach的时候创建出来的,这注意两行关键代码mWindow.setWindowControllerCallback(this)和mWindow.setCallback(this),因为Activity继承了Window的Callback,所以可以将Activity作为PhoneWindow的回调设置进去,后面PhoneWindow接收到的消息和一些其它操作都是通过这个回调告诉Activity。
    part3,创建了Activity和attach之后,就调用到了我们熟悉的Activity的OnCreate

    public void callActivityOnCreate(Activity activity, Bundle icicle,
                PersistableBundle persistentState) {
            prePerformCreate(activity);
            activity.performCreate(icicle, persistentState);
            postPerformCreate(activity);
        }
    
    final void performCreate(Bundle icicle) {
            restoreHasCurrentPermissionRequest(icicle);
            onCreate(icicle);//onCreate中比如MainActivity继承Activity,就调用到了MainActivity的onCreate函数
            mActivityTransitionState.readState(icicle);
            performCreateCommon();
        }
    

    至此终于见到我们熟悉的Activity的onCreate和setContentView(R.layout.activity_main)函数了。setContentView在Activity中如下

    public void setContentView(@LayoutRes int layoutResID) {
            getWindow().setContentView(layoutResID);
            initWindowDecorActionBar();
        }
    

    getWindow()返回的是mWindow,就是在上面attach中创建的PhoneWindow,那么PhoneWindow的setContentView又做了什么呢。我们xml布局的视图又是如何了呢。

    public void setContentView(int layoutResID) {
            // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
            // decor, when theme attributes and the like are crystalized. Do not check the feature
            // before this happens.
            if (mContentParent == null) {
                installDecor();
            } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
                mContentParent.removeAllViews();
            }
    
            if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
                final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
                        getContext());
                transitionTo(newScene);
            } else {
                mLayoutInflater.inflate(layoutResID, mContentParent);
            }
        }
    
    private void installDecor() {
    mForceDecorInstall = false;
            if (mDecor == null) {
                mDecor = generateDecor(-1);
            } 
            if (mContentParent == null) {
                        mContentParent = generateLayout(mDecor);
            }
    }
    
    protected DecorView generateDecor(int featureId) {
            return new DecorView(context, featureId, this, getAttributes());
        }
    
    

    到这里我们终于见到DecorView了,DecorView它是什么东西呢,它是继承FrameLayout的布局,也就是这里我们终于见到了View,现在也明白了Activity的顶布局是DecorView了,我们的xml布局中的View只是DecorView的Content布局内容。

    public class DecorView extends FrameLayout implements RootViewSurfaceTaker, WindowCallbacks {
    

    但到目前为止我们仅仅只见到过Activity的创建和它OnCreate函数的运行,也知道了我们的xml视图实例化之后加入到了DecorView中,这样就显示了视图,如何接收onTouchEvent事件了吗,当然不是。这才是一部分,或者称之为View视图已经准备好了,已经创建了,剩下就是如何显示它们了。

    显示Activity或者说显示View

    回到开始的handleLaunchActivity,第一部分创建Activity或者说创建View也即运行完performLaunchActivity函数之后,来到了handleResumeActivity函数,如下:

    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
            
            Activity a = performLaunchActivity(r, customIntent);
    
            if (a != null) {
                handleResumeActivity(r.token, false, r.isForward,
                        !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
      }
    }
    
    final void handleResumeActivity(IBinder token,
                boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
            ActivityClientRecord r = mActivities.get(token);
            if (!checkAndUpdateLifecycleSeq(seq, r, "resumeActivity")) {
                return;
            }
            r = performResumeActivity(token, clearHide, reason);
    
            if (r != null) {
                final Activity a = r.activity;
                  .
                  .
                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) {
                        a.mWindowAdded = true;
                        wm.addView(decor, l);
                    }
    }
    

    其中的performResumeActivity会最终运行到Activity的Resume函数。但是这个时候其实我们的View是没有显示的,那Activity都Resume了View还没有显示,那是什么时候显示呢,往下看注意这段代码wm.addView(decor, l);decor是上文中的DecorView对象,wm是什么呢,ViewManager wm = a.getWindowManager()

    public WindowManager getWindowManager() {
            return mWindowManager;
        }
    

    那mWindowManager是什么实例呢,它又是在什么地方创建或者赋值的,Activity的attach中有一行mWindowManager = mWindow.getWindowManager(),也就是说mWindowManager是获取的PhoneWindow的对象。继续往下跟Window类中有一个setWindowManager函数

    public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
                boolean hardwareAccelerated) {
            mAppToken = appToken;
            mAppName = appName;
            mHardwareAccelerated = hardwareAccelerated
                    || SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false);
            if (wm == null) {
                wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
            }
            mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
        }
    

    PhoneWindow继承Window,注意attach中有一段

    mWindow.setWindowManager(
                    (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                    mToken, mComponent.flattenToString(),
                    (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
    

    也就是说mWindowManager是我们的mContext.getSystemService(Context.WINDOW_SERVICE)获取到的WINDOW_SERVICE调用的createLocalWindowManager创建的WindowManagerImpl对象

    public final class WindowManagerImpl implements WindowManager {
        //注意这个WindowManagerGlobal,它是一个单例对象,就是说一个进程只有一个实例
        private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
        public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
               return new WindowManagerImpl(mContext, parentWindow);
        }
    }
    

    mContext为Context对象,Context是一个抽象类,它的实现类是ContextImpl,查看ContextImpl的getSystemService函数,最终调用到了SystemServiceRegistry的getSystemService,而getSystemService返回的是它的HashMap SYSTEM_SERVICE_FETCHERS中保存的注册的服务,一下就是我们常用到的ActivityManager和WindowManager

    @Override
        public Object getSystemService(String name) {
            return SystemServiceRegistry.getSystemService(this, name);
        }
    
    final class SystemServiceRegistry {
        private static final HashMap<Class<?>, String> SYSTEM_SERVICE_NAMES =
                new HashMap<Class<?>, String>();
        private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
                new HashMap<String, ServiceFetcher<?>>();
        private static int sServiceCacheSize;
    
        // Not instantiable.
        private SystemServiceRegistry() { }
    
        static {
            registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
                    new CachedServiceFetcher<ActivityManager>() {
                @Override
                public ActivityManager createService(ContextImpl ctx) {
                    return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
                }});
            registerService(Context.WINDOW_SERVICE, WindowManager.class,
                    new CachedServiceFetcher<WindowManager>() {
                @Override
                public WindowManager createService(ContextImpl ctx) {
                    return new WindowManagerImpl(ctx);
                }});
    }
    

    回到handleResumeActivity中的wm.addView(decor, l);,也就是调用到了WindowManagerImpl的addView

    @Override
        public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
            applyDefaultToken(params);
            mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
        }
    

    最终调用到了WindowManagerGlobal中的addView,它里面又做了什么呢

    public final class WindowManagerGlobal {
            private final ArrayList<View> mViews = new ArrayList<View>();
            private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();
            public void addView(View view, ViewGroup.LayoutParams params,
                        Display display, Window parentWindow) {
                    ViewRootImpl root;
                    View panelParentView = null;
    
                    synchronized (mLock) {
                        int index = findViewLocked(view, false);
                        root = new ViewRootImpl(view.getContext(), display);
                        view.setLayoutParams(wparams);
    
                        mViews.add(view);
                        mRoots.add(root);
                        mParams.add(wparams);
                    }
    
                    // do this last because it fires off messages to start doing things
                    try {
                        root.setView(view, wparams, panelParentView);
                    } catch (RuntimeException e) {
                    }
             }
    }
    

    这里我们终于见到了ViewRootImpl。但是,什么,做了这么多,就是看到new了一个ViewRootImpl对象,然后将View和new的ViewRootImpl对象分别add到mViews和mRoots列表中,说好的显示View呢,怎么接收Event等呢。add就行了吗?这个就要从ViewRootImpl的setView说起了,说说ViewRootImpl了。

    public final class ViewRootImpl implements ViewParent,
            View.AttachInfo.Callbacks, ThreadedRenderer.HardwareDrawCallbacks {
    public ViewRootImpl(Context context, Display display) {
            mContext = context;
            //代表WindowManagerService的WindowSession
            mWindowSession = WindowManagerGlobal.getWindowSession();
            mDisplay = display;
            mBasePackageName = context.getBasePackageName();
            mThread = Thread.currentThread();
            mWinFrame = new Rect();
            //代表WindowManagerService和ViewRootImpl通信的mWindow,W对象
            mWindow = new W(this);
            mFirst = true; // true for the first time the view is added
            mAdded = false;
            //代表View和ViewRootImpl关联的对象AttachInfo
            mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this);
            mFallbackEventHandler = new PhoneFallbackEventHandler(context);
            //我们常常说的编舞者对象Choreographer,控制UI刷新的,怎么做的1s内刷新60HZ的
            mChoreographer = Choreographer.getInstance();
            mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
            loadSystemProperties();
        }
    }
    

    ViewRootImpl的构造函数中的几个关键对象都作了注释 //代表WindowManagerService的WindowSession//代表WindowManagerService和ViewRootImpl通信的mWindow,W对象//代表View和ViewRootImpl关联的对象AttachInfo//我们常常说的编舞者对象Choreographer,控制UI刷新的,怎么做的1s内刷新60HZ的。
    上文说的要从ViewRootImpl的setView说起,setView怎么说呢,代码比较长,截取关键部分

    public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
            synchronized (this) {
                if (mView == null) {
                    mView = view;
    
                    mAttachInfo.mDisplayState = mDisplay.getState();
                    mDisplayManager.registerDisplayListener(mDisplayListener, mHandler);
    
                    // If the application owns the surface, don't enable hardware acceleration
                    if (mSurfaceHolder == null) {
                        enableHardwareAcceleration(attrs);//硬件加速初始化部分
                    }
    // Schedule the first layout -before- adding to the window
                    // manager, to make sure we do the relayout before receiving
                    // any other events from the system.
                    requestLayout();
                    if ((mWindowAttributes.inputFeatures
                            & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
                        mInputChannel = new InputChannel();
                    }
                    mForceDecorViewVisibility = (mWindowAttributes.privateFlags
                            & PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY) != 0;
                    try {
                        mOrigWindowType = mWindowAttributes.type;
                        mAttachInfo.mRecomputeGlobalAttributes = true;
                        collectViewAttributes();
                        //mWindowSession添加窗口显示,一个应用只分配一个sWindowSession
                        res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
                                getHostVisibility(), mDisplay.getDisplayId(),
                                mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
                                mAttachInfo.mOutsets, mInputChannel);
                    } catch (RemoteException e) {
                    }
                  //mInputChannel,输入通道,WindowInputEventReceiver,输入事件接收相关代码
                  if (mInputChannel != null) {
                        if (mInputQueueCallback != null) {
                            mInputQueue = new InputQueue();
                            mInputQueueCallback.onInputQueueCreated(mInputQueue);
                        }
                        mInputEventReceiver = new WindowInputEventReceiver(mInputChannel,
                                Looper.myLooper());
                    }
    }
    

    setView中的enableHardwareAcceleration(attrs)是关于硬件加速的,设计到View的
    Draw问题,mWindowSession的addToDisplay是将视图和窗口关联的过程。mInputChannel输入通道,WindowInputEventReceiver接收输入事件,有了这些一个app的完整的显示,UI更新,接收事件等终于准备好了,剩下的就是点击屏幕,事件如何传递到Activity和View的问题,View如何将内容显示出来,并且不断的进行UI更新,这个就是Choreographer和Draw的问题,而怎么Draw就涉及到硬件加速Draw和softDraw,本篇就先到这,下篇再讲。
    这里我们总结下ActivityThread接收到ActivityManagerService通过Binder调用,创建Activity的过程,这些过程是平时做应用开发会有所涉及的。

    1:ActivityThread的mAppThread成员变量调用scheduleLaunchActivity成员函数准备启动Activity,发送LAUNCH_ACTIVITY转换给ActivityThread的H类对象mH处理(转换到主线程处理)。
    2:mH对象接收到LAUNCH_ACTIVITY消息之后handleMessage调用handleRelaunchActivity成员函数,参数为ActivityClientRecord对象,表示记录Activity的一些Client端信息,比如包名,组件名称等等。
    3:handleLaunchActivity函数中调用performLaunchActivity,执行启动Activity。
       3.1:performLaunchActivity函数调用mInstrumentation new出需要启动的Activity,比如MainActivity
            3.1.1:new出Activity之后,通过调用LoadedApk的makeApplication,创建应用的Application对象,同时创建Activity自己的Context
                  3.1.2:这一切准备好之后,调用Activity的attach函数。
                         3.1.2.1:attach中主要创建了PhoneWindow对象,作为Activity对应的Window对象。
                  3.1.3:Activity的attach运行完成之后通过mInstrumentation调用Activity的OnCreate,调用到我们熟悉的OnCreate函数
                         3.1.3.1:OnCreate·函数中,调用setContentView。这时会new出Activity窗口的根布局DecorView同时将我们自己的xml布局实例化成View,并添加到DecorView根布局中。
       3.2:handleResumeActivity函数运行完成之后执行handleResumeActivity,在handleResumeActivity函数中将DecorView加入到WindowManager中,
           在add DecorView的过程中创建了ViewRootImpl对象。ViewRootImpl对象完成UI Draw,消息接收等,细节后续篇章讲解。
    4:进入Looper消息循环,等等消息输入
    

    相关文章

      网友评论

          本文标题:从Android app说起

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