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();
        }
相关推荐
消失的旧时光-19434 小时前
从 C 链表到 Android Looper:MessageQueue 的底层原理一条线讲透
android·数据结构·链表
方白羽4 小时前
Android 中Flags从源码到实践
android·app·客户端
深蓝电商API4 小时前
从数据采集到商业变现:网络爬虫技术的实战与边界
android·爬虫
恋猫de小郭6 小时前
再次紧急修复,Flutter 针对 WebView 无法点击问题增加新的快速修复
android·前端·flutter
李慕婉学姐6 小时前
【开题答辩过程】以《基于Android的健康助手APP的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
android·java·mysql
似霰8 小时前
传统 Hal 开发笔记6----App 访问硬件服务
android·framework·hal
爱装代码的小瓶子9 小时前
【c++知识铺子】封装map和set(详细版)
android·java·c++
私人珍藏库9 小时前
AutoGLM无需豆包手机,让AI自动帮你点外卖-刷视频
android·ai·智能手机·工具·软件·辅助·autoglm
孤舟簔笠翁10 小时前
【Android驱动14】Android系统Crash工具使用方法和分析
android