SurfaceControlViewHost 实现跨进程UI渲染

背景

在学习photo picker文档时,看到了这样一个描述;可以通过一种方法,将另一个进程的复杂页面渲染到当前页面中,并支持做复杂交互,且具备一定的安全性和隐私性保护。结合之前项目上的一个诉求(给第三方业务暴露登陆按钮,但不想让业务方得知实现细节,避免业务方后台调用该按钮后台偷偷登陆)感觉可以用这种方式去实现,因此去了解下细节

实现效果

实现方式:

1、使用SurfaceControlViewHost + SurfaceView 实现

SurfaceView原理: 核心是把主进程的surface传递给单独的渲染进程,从而实现跨进程渲染的效果

SurfaceControlViewHost: 并提供将渲染进程的view嵌入到主进程中

使用步骤

客户端(主进程):

--创建用于展示内容的,surfaceView,提供host token确定是具体哪个surface View,提供display ID,用于渲染的一些基础依赖(字体大小等)

--获取服务端返回的SurfacePackage,与surfaceView绑定

--事件通知,所有input事件,通知服务器

服务端(渲染进程):

--使用客户端提供的display ID、hostToken 创建SurfaceControlViewHost,创建自定义view,返回SurfacePackage给客户端

--接收input事件,传递给自定义view

java 复制代码
//aidl
interface IRemoteRender {
    //客户端提供surface、大小、display 从服务端获取 surfacePackage
    SurfacePackage getSurfacePackage(int displayId, IBinder hostToken, int width, int height);
    //客户端向服务端传递 事件
    boolean onTouch(in MotionEvent motionEvent);
}
 
//服务端
    private final IRemoteRender.Stub mBinder = new IRemoteRender.Stub() {
 
        @Override
        public SurfaceControlViewHost.SurfacePackage getSurfacePackage(int displayId, IBinder hostToken, int width, int height) {
            Log.i(TAG, "getSurfacePackage, displayId=" + displayId + ", hostToken=" + hostToken + ", width=" + width + ", height=" + height);
            final SurfaceControlViewHost.SurfacePackage[] result = new SurfaceControlViewHost.SurfacePackage[1];
            final CountDownLatch latch = new CountDownLatch(1);
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    // 创建SurfaceControlViewHost
                    Context context = getBaseContext();
                    Display display = context.getSystemService(DisplayManager.class).getDisplay(displayId);
                    mSurfaceControlViewHost = new SurfaceControlViewHost(context, display, hostToken);
                    createRootView(width,height);
                    // 将视图附加到SurfaceControlViewHost
                    mSurfaceControlViewHost.setView(mRootView, width, height);
                    result[0] = mSurfaceControlViewHost.getSurfacePackage();
                    latch.countDown();
                }
            });
 
            try {
                latch.await(); // 等待主线程完成操作
                return result[0];
            } catch (InterruptedException e) {
                Log.i(TAG, "getSurfacePackage, e=" + e.getMessage());
            }
            return null;
        }
 
        @Override
        public boolean onTouch(MotionEvent event) throws RemoteException {
            final CountDownLatch latch = new CountDownLatch(1);
            final boolean[] result = {true};
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    mRootView.dispatchTouchEvent(event);
                    latch.countDown();
                }
            });
            try {
                latch.await(); // 等待主线程完成操作
                return result[0];
            } catch (InterruptedException e) {
                Log.i(TAG, "getSurfacePackage, e=" + e.getMessage());
            }
            return true;
        }
    };
 
 
//客户端
      try {
            IBinder hostToken = mSurfaceView.getHostToken();
            SurfaceControlViewHost.SurfacePackage surfacePackage = mRemoteRender.getSurfacePackage(0, hostToken, 1000, 2000);
            mSurfaceView.setChildSurfacePackage(surfacePackage);
            mSurfaceView.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {
 
                    try {
                        return mRemoteRender.onTouch(motionEvent);
                    } catch (RemoteException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        } catch (RemoteException e) {
            e.printStackTrace();
        }
相关推荐
Cutecat_14 小时前
视频字幕处理工具横向:提取模式 vs 编辑模式,该如何选择
android·前端·ios·语音识别
2601_9617652915 小时前
【分享】PlayerPro媒体音乐播放器 完整专业版
android·媒体
JohnnyDeng9417 小时前
【Android】Android 包体积优化:R8/ProGuard 深度配置全攻略
android·性能优化·kotlin·jetpack
故渊at17 小时前
第九板块:Android 多媒体体系 | 第二十四篇:Camera Service 与 HAL3 成像流水线
android·camera·多媒体体系·hal3
Jinkxs20 小时前
Python基础 - 初识内置函数 Python自带的便捷工具
android·java·python
私人珍藏库21 小时前
【Android】VLLO-韩国热门手机剪辑APP
android·app·工具·软件·多功能
Cloud_Shy61821 小时前
解读《Effective Python 3rd Edition》:从练气到老魔(第六章 Item 40 - 43)
android·开发语言·人工智能·笔记·python·学习方法
AFinalStone1 天前
Android12 U盘插拔链路源码全解析(五):Framework层(下) StorageManagerService
android·frameworks
林九生1 天前
【实用技巧】MySQL 绿色版一键路径更新脚本详解 —— update_path.bat 深度解析
android·数据库·mysql
故渊at1 天前
第十三板块:Android 综合架构与未来演进 | 第三十一篇:Android 架构演进与 Fuchsia OS 的挑战
android·架构·宏内核·微内核·fuchsia·ipc 性能博弈