ActivityView source code solution analysis of Android 10 car CarLauncher

Hi fans and friends:
Hello everyone!

1 Explore ActivityView background reasons

Free video tutorials at station b:
https://www.bilibili.com/video/BV1wj411o7A9/
Insert image description here

The previous blogs are all CarLauncher implementation solutions that analyze the latest android 13 source code. We already know that CarLauncher uses TaskView to load new map tasks. However, before the android 12 version, it was not implemented using the TaskView solution, but ActivityView scheme used.

However, CarLauncher also implements CarLauncher's Activity to embed another map Activity, so it is necessary to understand it below.

2 Source code analysis

创建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);
    }

Related construction methods of 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);

    }

It can be seen from the above that ActivityView is a ViewGroup, and a SurfaceView is constructed in the construction method.

Next is the surfaceCreated of SurfaceView to trigger:

 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);
                }
            }
//省略

        }
        }

Let’s take a look at the core method 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);
        }
    }

The corresponding display has been prepared above. The next step is to start the related Activity under this display.

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());
        }
    }

Let’s take a look at 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;
    }   

After the above ActivityOption setting setLaunchDisplayId is completed, then the Activity starts on the new display.
Insert image description here

Guess you like

Origin blog.csdn.net/learnframework/article/details/131953601