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();
        }
相关推荐
拥小抱4 小时前
Compose 知识点
android
文章永久免费只为良心4 小时前
Web应用安全与防护_第三章_日志文件包含_从一道 CTFshow 题目讲透「日志投毒型 LFI → RCE」:原理、时序陷阱与全变种攻防手册
android·网络安全·渗透测试·漏洞危害·漏洞描述·日志投毒·红队指南
AIsoft_86895 小时前
学术讲座录音如何整理?录音APP可行吗
android·iphone
Patrick在香港7 小时前
一个斜杠,把毫秒变成十几秒
android·数据库·python·性能优化·正则表达式·回溯·redos
海雅达手持终端PDA9 小时前
工业手持终端的“去手机化”演进:看海雅达如何以“同轴扫摄”终结工程妥协,重塑工业PDA新范式
android·物联网·智能手机·硬件工程·能源·制造·iot
booboosui10 小时前
删掉一个住在本机的 agent:8 处要清,顺序不能反
android
hcgeng10 小时前
Android获取崩溃日志
android
aqi0010 小时前
AI编程让鸿蒙开发电子书APP更加快捷
android·华为·harmonyos·鸿蒙·harmony
GY-9310 小时前
【Android】Android Studio 中的协程
android