【Android车载系列】第4章 Activity启动到渲染到SurfaceFlinger流程

13 篇文章 45 订阅
9 篇文章 9 订阅

1 Activity的创建

  ActivityThread对于App进程来说,它是App的入口。此外ActivityThread还实现了创建主线程Looper、dump应用内存使用情况、获取应用包名等接口。我们看看ActivityThread对于四大组件的作用,一句话概括,ActivityThread管理着四大组件的生命周期方法的调用。
  AMS服务进程发出信号触发App内的ActivityThread通过反射实例化Activity并启动Activity,然后调用activity的attach()方法。

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    //...
   ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            // 通过反射创建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);
            }
        }


    //调用activity的attach方法
   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);

    //...
}

  然后开始了Activity的生命周期。执行onCreate()-onStart()-onResume(),onResume()执行时页面还不可见,onResume()完全执行完之后的第一个VSYNC信号后页面才可见。onResume()DecorView添加到WindowManagerGlobal中。

 @Override
    public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
            String reason) {
        // ...
        // The window is now visible if it has been added, we are not
        // simply finishing, and we are not starting another activity.
        if (r.window == null && !a.mFinished && willBeVisible) {
            // 获取到PhoneWindow和DecorView
            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 (r.mPreserveWindow) {
                a.mWindowAdded = true;
                r.mPreserveWindow = false;
                // Normally the ViewRoot sets up callbacks with the Activity
                // in addView->ViewRootImpl#setView. If we are instead reusing
                // the decor view we have to notify the view root that the
                // callbacks may have changed.
                ViewRootImpl impl = decor.getViewRootImpl();
                if (impl != null) {
                    impl.notifyChildRebuilt();
                }
            }
            if (a.mVisibleFromClient) {
                if (!a.mWindowAdded) {
                    a.mWindowAdded = true;
                    // wm是WindowManagerImpl,
                    // 将DecorView add到App的单例WindowManagerGlobal中
                    wm.addView(decor, l);
                } else {
                    // The activity will get a callback for this {@link LayoutParams} change
                    // earlier. However, at that time the decor will not be set (this is set
                    // in this method), so no action will be taken. This call ensures the
                    // callback occurs with the decor set.
                    a.onWindowAttributesChanged(l);
                }
            }

            // If the window has already been added, but during resume
            // we started another activity, then don't yet make the
            // window visible.
        } else if (!willBeVisible) {
            if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");
            r.hideForNow = true;
        }
    }

2 Activity的渲染

  Activity的attach()方法内会初始化一个PhoneWindow对象(一个Activity对应一个PhoneWindow对象)。
  Android系统AMS服务通过Binder与ActivityThread进行通讯,ActivityThread将App内所有Activity的页面进行管理。每个Activity中有一个对应的PhoneWindow,每个PhoneWindow有对应的DecorView,DecorView是布局内layout的容器
在这里插入图片描述

3 WindowManagerGlobal

  每个App都只有一个WindowManagerGlobal对象,App层的单例对象。ActivityThread通过WindowManagerImpl与WindowManagerGlobal实现通讯,WindowManagerGlobal用于缓存所有页面的PhoneWindow、DecorView、ViewRootImpl等界面相关的数据
  WindowManagerGlobal内部有addView()removeView()等增删查的所有方法都是通过遍历的形式进行逻辑处理,对外提供服务。
  主要给WMS提供管理所有View的便利。由于与WMS是SystemServer进程中,和App属于不同进程,所有使用的是Binder进程间通讯。在这里插入图片描述

4 WindowManagerService

  WindowManagerService窗口管理服务简称WMS,一台设备只有一个WMS。WMS管理所有App的全部PhoneWindow
  WindowManagerGlobal利用Session跨进程通过WMS与SurfaceFlinger通讯。根据每个不同的应用一一对应创建一个Surface,用于该应用的渲染。
在这里插入图片描述

5 建立Surface和SurfaceFlinger连接

SurfaceFlinger服务主要实现了两个Binder service用于App连接:
1) SurfaceFlinger
  派生自BnSurfaceComposer,是SurfaceFlinger程序的主服务,在程序启动时就被构造并添加到servicemanager,相关代码在main_surfaceflinger.cpp,服务名为”SurfaceFlinger”
2) Client
  派生自BnSurfaceComposerClient,在SurfaceFlinger:: createConnection的时候被创建,对应一个App Client连接

然后App启动后,需要通过如下操作和SurfaceFlinger建立会话:
1)通过servicemanager获取服务SurfaceFlinger的BpBinder,然后转换成BpSurfaceComposer
2)调用BpsurfaceComposer.createConnection建立连接,然后将返回的BpBinder转换成BpSurfaceComposeClient

Android接着提供了两个类用于简化App端的操作,主要包括:
1)ComposerService
  单列类,主要封装跟SurfaceFlinger的连接,在构造时调用connectlocaked成员函数连接
“SurfaceFlinger”然后将BpSurfaceCompose保存到成员变量mComposerService
2)SurfaceComposerClient
  封装跟SurfaceFlinger建立会话连接的操作,在onFirstRef时调用createConnection建立
会话并将BpSurfaceComposerClient保存到成员变量mClient
3)Composer
  单列类,主要封装对Layer数据配置相关操作

接下去基于代码来分析,封装好后,App初始化连接很简单

sp<SurfaceComposerClient> session= new SurfaceComposerClient();

就一行代码,接着看构造函数

SurfaceComposerClient::SurfaceComposerClient()
    : mStatus(NO_INIT), mComposer(Composer::getInstance()){
}

获取Composer单例对象并保存到mComposer,由于SurfaceComposerClient派生自RefBase

class SurfaceComposerClient : public RefBase

所以在其构造时,会调用incStrong第一次增加强引用计数,同时onFirstRef会被调用

void SurfaceComposerClient::onFirstRef() {
    sp<ISurfaceComposer> sm(ComposerService::getComposerService());
    if (sm != 0) {
        sp<ISurfaceComposerClient> conn = sm->createConnection();
        if (conn != 0) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}

这个函数完成了连接的最终操作,先是通过ComposerService::getComposerService()生成
ComposeService单列,并调用其connectLocked连接SurfaceFlinger返回BpSurfaceComposer,接着调用sm->createConnection()创建会话并保存到mClient。接下来看看SurfaceFlinger.createConnection的代码

sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
{
    sp<ISurfaceComposerClient> bclient;
    sp<Client> client(new Client(this));
    status_t err = client->initCheck();
    if (err == NO_ERROR) {
        bclient = client;
    }
    return bclient;
}

很简单,就是创建Client本地对象并返回

到这里,App跟SurfaceFlinger的初始化连接已经结束,接下去就是基于会话对象,创建绘图表面了

6 流程图

在这里插入图片描述

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

__Yvan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值