Android 显示子系统简介

目录

1 相关概念介绍

2.关键概念的关系

2.1 Activity、PhoneWindow、DecorView、ViewRootImpl、Choreographer、Surface的创建和关系

2.1.1 Activity 创建:APP拥有Activity

2.1.2 Window的创建:Activity拥有Window

2.1.3 DecorView的创建:Window拥有DecorView

2.1.4 ViewRootImpl的创建:DecorView拥有ViewRootImpl

2.1.5 Surface的创建:ViewRootImpl拥有Surface

2.1.6 Choreographer的创建:ViewRootImpl拥有Choreographer

2.1.7 Activity、PhoneWindow(Window)、DecorView、ViewRootImpl和Surface之间的关系说明什么

2.2 SurfaceView

2.3 Layer的创建

3. 总结和后续分享计划

3.1 总结

3.2 分享计划


1 相关概念介绍

说到显示系统,或者我们平时做流畅性时候,常常可以碰到如下的一些关键字。本文希望通过对一些流程的简单介绍,把这些概念串联起来,看看App,system_sever(这里主要是wms),surfaceflinger之间是如何协同工作的

  1. View: 视图,绘制到屏幕上的内容,如 TextView, ImageView 等。
  2. Window: View 的载体,对 Window 进行添加和删除需要通过 WindowManager 来操作。Window 并不是真实存在的,View 才是 Android 中的视图呈现形式,View 不能单独存在,它必须依附在 Window 这个抽象的概念上面。
  3. WindowManager: 管理系统中的 Window, 实际功能通过 Binder IPC 借由 WindowManagerService 实现。
  4. Surface: 一个 Window 对应一个 Surface(当存在 SurfaceView 则例外)。Surface 内部持有一个 BufferQueueProducer 指针(在 Layer 中创建)可以生产图像缓存区用来绘图,与 App 和 SurfaceFlinger 形成一个生产者消费者模型。
  5. Layer: App 请求创建 Surface 时 SurfaceFlinger 会创建 Layer 对象,它是 SurfaceFlinger 合成的基本操作单元,一个 Surface 对应一个 Layer
  6. SurfaceView: 一种比TextView, imageview特殊的 View, 它不与其宿主的 Window 共享一个 Surface, 而是有自己的独立 Surface。并且它可以在一个独立的线程中绘制 UI。 SurfaceView 一般用来实现比较复杂界面显示h比较常见的就是视频。
  7. Choreographer: 编舞者,用来控制当收到 VSync 信号后才开始绘制任务,周期一般是16.6\11.1\8.3ms,它作为一个节拍器在控制应用的绘制
  8. SurfaceFlinger: 管理消费当前可见的 Surface,所有被渲染的可见 Surface 都被 SurfaceFlinger,通过 WindowManager 提供的信息合成,提交到屏幕的后缓冲区,等待屏幕的下一个Vsync信号到来,再显示到屏幕上。SufaceFlinger 在屏幕和上层之间起到了一个承上启下的作用。
  9. HWComposer: HardWare Composer, 定义一套 HAL 层接口,芯片厂商根据硬件特点来实现这套接口。其主要工作是将 SurfaceFlinger 计算后的 Layer 显示参数合成到显示器 Buffer 上。当然 SurfaceFlinger 并非是 HWC 的唯一输入源,例如摄像头的预览输入 Buffer 可以由硬件设备直接写入,然后作为 HWC 的输入之一与 SurfaceFlinger 的输出做最后的合
  10. Gralloc: 图形内存分配器,用来分配图像生产者请求的内存

2.关键概念的关系

2.1 Activity、PhoneWindow、DecorView、ViewRootImpl、Choreographer、Surface的创建和关系

2.1.1 Activity 创建:APP拥有Activity

点击应用图标,会通过Zygote创建一个进程,然后调用调应用的ActivityThread main,最终调用ActivityThread.handleLaunchActivity

1.handleLaunchActivity 调用performLaunchActivity创建一个Actiivty

2.performLaunchActivity调用mInstrumentation.newActivity创建Activity

3.performLaunchActivity还会创建一个进程,作为这些资源的载体

这些都是跑在ActivityThread中的,也就是应用的主线程,到这来就APP就拥有了Activity

 /**
     * Extended implementation of activity launch. Used when server requests a launch or relaunch.
     */
    @Override
    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        // 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
        if (!ThreadedRenderer.sRendererDisabled
                && (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
            HardwareRenderer.preload();
        }
        WindowManagerGlobal.initialize();

        // Hint the GraphicsEnvironment that an activity is launching on the process.
        GraphicsEnvironment.hintActivityLaunch();
        //1. 调用performLaunchActivity创建一个Activity
        final Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            if (!r.activity.mFinished && pendingActions != null) {
                pendingActions.setOldState(r.state);
                pendingActions.setRestoreInstanceState(true);
                pendingActions.setCallOnPostCreate(true);
            }
        } else {
            // If there was an error, for any reason, tell the activity manager to stop us.
            try {
                ActivityTaskManager.getService()
                        .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                                Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }

        return a;
    }
    
    
     /**  Core implementation of activity launch. */
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ......
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            // 2. 调用mInstrumentation.newActivit创建一个Activity
            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);
            }
        }

        try {
            //3. 创建一个进程        
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

           ......

        return activity;
    }               

2.1.2 Window的创建:Activity拥有Window

接着2.1.1,调用到performLaunchActivity后会创建Actvity和Application,同时还会调用

1. 调用 activity.attach通过该方法创建一个Window

2.由于Window本身是个抽象类,因此在创建的时候会创建它的具体实现类PhoneWindow

到这里Actvity拥有了自己的Window:mWindow

         /**  Core implementation of activity launch. */
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ......
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.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);
            }
        }

        try {             
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

           ......
           
        if (activity != null) {
                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;
                }
                appContext.setOuterContext(activity);
                //1. 调用  activity.attach通过该方法创建一个Window     
                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, r.configCallback,
                        r.assistToken)
                 
              }

        return activity;
    }  
    
    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, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {
        attachBaseContext(context);

        mFragments.attachHost(null /*parent*/);
        //2.创建一个PhoneWindow
        mWindow = new PhoneWindow(this, window, activityConfigCallback);
       ......
    }

2.1.3 DecorView的创建:Window拥有DecorView

接着2.1.1和2.1.2,调用到performLaunchActivity后会创建Actvity和Application,创建window,然后还会调用mInstrumentation.callActivityOnCreate,这个最终会调用调应用自己实现的具体Activity类中去,调用的该具体类的Actvity的OnCreate,exp:如下代码中的MainActivity,应用会在这里调用setContentView.

1.Activity的setContentView被调用,在这个函数中会去调用对应PhoneWindow的setContentView

2.Window的setContentView,在这个函数中会通过installDecor来创建为PhoneWindow创建DecorVIew

到这来Window拥有了自己的DecorView:mDecor

//frameworks/base/core/java/android/app/ActivityThrea
  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值