android 10车载CarLauncher的ActivityView源码方案分析

hi粉丝朋友们:
大家好!

1 探索ActivityView背景原因

b站免费视频教程讲解:
https://www.bilibili.com/video/BV1wj411o7A9/
在这里插入图片描述

前面的blog都是对于最新的android 13源码进行分析的CarLauncher的实现方案,已经知道CarLauncher使用是TaskView来装载新的地图Task,但是在android 12版本以前其实不是使用的TaskView的方案实现的,而是使用的ActivityView方案。

但是CarLauncher一样实现了CarLauncher的Activity进行内嵌另一个地图Activity,那么下面就有必要来了解一下

2 源码分析

创建ActivityView
package/apps/Car/Launcher/src/com/android/car/carlauncher/CarLauncher.java

  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
      //省略部分
      //ActivityView直接在xml中已经定义好了,其实它就是个ViewGroup
        mActivityView = findViewById(R.id.maps);
    }

ActivityView的相关构造方法:
base/core/java/android/app/ActivityView.java

 public ActivityView(
            Context context, AttributeSet attrs, int defStyle, boolean singleTaskInstance) {
        super(context, attrs, defStyle);
    //创建对应的SurfaceView
        mSurfaceView = new SurfaceView(context);
      //添加到了ActivityView的容器
        addView(mSurfaceView);

    }

上面可以看出ActivityView就是个ViewGroup,构造方法里面构造了一个SurfaceView

接下来就是SurfaceView的surfaceCreated来触发:

 private class SurfaceCallback implements SurfaceHolder.Callback {
        @Override
        public void surfaceCreated(SurfaceHolder surfaceHolder) {
            if (mVirtualDisplay == null) {
            //初始化虚拟display
                initVirtualDisplay(new SurfaceSession());
                if (mVirtualDisplay != null && mActivityViewCallback != null) {
                //回调onActivityViewReady,主要是触发startActivity
                    mActivityViewCallback.onActivityViewReady(ActivityView.this);
                }
            }
//省略

        }
        }

下面看看核心方法initVirtualDisplay:

private void initVirtualDisplay(SurfaceSession surfaceSession) {
    //创建对应的display
        mVirtualDisplay = displayManager.createVirtualDisplay(
                DISPLAY_NAME + "@" + System.identityHashCode(this), width, height,
                getBaseDisplayDensity(), null,
                VIRTUAL_DISPLAY_FLAG_PUBLIC | VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
                        | VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL);
      //获取displayId
        final int displayId = mVirtualDisplay.getDisplay().getDisplayId();
        final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
		//给surfaceiew的surfacecontrol多创建一个子surfacecontrol,专门装载新的display
        mRootSurfaceControl = new SurfaceControl.Builder(surfaceSession)
                .setContainerLayer()
                .setParent(mSurfaceView.getSurfaceControl())
                .setName(DISPLAY_NAME)
                .build();

   //把新的displayreparent到前面的mRootSurfaceControl
            WindowManagerGlobal.getWindowSession().reparentDisplayContent(
                    getWindow(), mRootSurfaceControl, displayId);
          //省略
        mTmpTransaction.show(mRootSurfaceControl).apply();
        mTaskStackListener = new TaskStackListenerImpl();
        try {
            mActivityTaskManager.registerTaskStackListener(mTaskStackListener);
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to register task stack listener", e);
        }
    }

上面已经准备好了对应的display了,下面一步就是启动这个display下面的相关Activity

private final ActivityView.StateCallback mActivityViewCallback =
            new ActivityView.StateCallback() {
                @Override
                public void onActivityViewReady(ActivityView view) {
                  //启动Maps的Activity
                    startMapsInActivityView();
                }
}


    private void startMapsInActivityView() {
      //实际上只是调用了mActivityView的startActivity
        if (mActivityView != null) {
            mActivityView.startActivity(getMapsIntent());
        }
    }

下面看看mActivityView.startActivity

 public void startActivity(@NonNull Intent intent) {
 //准备好对应的ActivityOption
        final ActivityOptions options = prepareActivityOptions();
        getContext().startActivity(intent, options.toBundle());
    }
    private ActivityOptions prepareActivityOptions() {
    //这里其实只是获取了新displayId,然后setLaunchDisplayId给ActivityOption
        final ActivityOptions options = ActivityOptions.makeBasic();
        options.setLaunchDisplayId(mVirtualDisplay.getDisplay().getDisplayId());
        return options;
    }   

上面ActivityOption设置setLaunchDisplayId完成后,那么Activity启动就是在新的display上面
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要下载Android车载导航Launcher源码,首先需要找到合适的网站或平台。可以通过搜索引擎搜索相关关键词,如“Android车载导航Launcher源码下载”来寻找相关资源。或者也可以通过开发者社区,如GitHub、StackOverflow等寻找开源项目。 一旦找到合适的下载资源,确保源码与您所需的功能和需求相匹配。仔细阅读项目的说明文档、许可证和用户评价等信息,确保该源码符合您的要求。 在进行下载之前,确保您具备开发环境以及相应的开发工具和技术知识。一般情况下,车载导航Launcher是基于Android平台的,因此您需要拥有Android开发环境和Android开发工具包(SDK)。 下载源码后,解压文件并打开项目。您可以使用Android Studio等IDE(集成开发环境)来导入项目,并根据您的需求进行配置和修改。 在进行任何修改之前,建议先阅读项目的文档和代码结构,熟悉项目的整体逻辑和功能。这样能更好地理解代码,并确保修改不会影响原有功能的稳定性和正确性。 修改完毕后,您可以根据自己的需要进行构建、编译和测试。确保应用在车载设备上的兼容性和稳定性。 最后,如果您对该源码进行了改进或优化,也可以考虑将您的成果贡献给开源社区,以便其他开发者也能受益。 总之,下载Android车载导航Launcher源码需要找到合适的下载资源、具备开发环境和工具、熟悉项目结构和代码逻辑、进行修改和测试。这样才能成功地下载并使用源码来满足您的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值