Webview独立进程并通过AIDL实现数据通信

前言:简单写下,目前代码也很粗糙

思路

步骤

实现独立进程

在AndroidManifest.xml文件中添加process属性就行,如下:

<activity
    android:name=".WebviewActivity"
    android:process=":webview" />
复制代码

创建IWebviewBinder,在主进程中处理JS调用Java的方法

/**
 * 主进程
 */
interface IWebviewBinder {

    /**
     * 处理JS调用Java的方法
     */
    void handleJsFunc(String methodName, String params, IWebviewBinderCallback callback);

}
复制代码

创建IWebviewBinderCallback,在主进程中处理JS调用Java的方法完成之后,在子进程中将数据回调给JS

/**
 * 子进程
 */
interface IWebviewBinderCallback {

    /**
     * 处理JS调用Java的方法之后,将数据回调给JS
     */
    void callJs(String params);

}
复制代码

创建MainRemoteService,创建IBinder对象,并在主进程中实现JS需要调用的Java方法。最后通过回调,在子进程中实现回调

/**
 * 主进程中的Service
 */
public class MainRemoteService extends Service {

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return serviceBinder;
    }

    private IWebviewBinder.Stub serviceBinder = new IWebviewBinder.Stub() {

        @Override
        public void handleJsFunc(String methodName, String params, IWebviewBinderCallback callback) throws RemoteException { //方法执行在子线程中
            new Handler().post(new Runnable() {
                @Override
                public void run() { //在主线程中执行下面代码
                    //操作主进程UI
                    //Toast.makeText(Utils.appContext, "processName = " + Utils.getCurrentProcessName() + ", params = " + params, Toast.LENGTH_SHORT).show();
                    //回调给子进程调用js
                    if (callback != null) {
                        try {
                            callback.callJs("javascript:alert('testJsonCallBack');");
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
        }

    };

}
复制代码

在子进程中绑定MainRemoteService,获得Service中创建的IBinder对象,并在连接成功后loadUrl

bindService(
        new Intent(this, MainRemoteService.class),
        connection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) { //方法执行在主线程中
                iWebviewBinder = IWebviewBinder.Stub.asInterface(iBinder);
                if (webView != null) {
                    webView.loadUrl(url);
                }
            }

            @Override
            public void onServiceDisconnected(ComponentName componentName) {

            }
        },
        Context.BIND_AUTO_CREATE);
复制代码

使用Service中创建的IBinder对象,并实现回调

jsInterface.setCallback(new JsInterface.JsFuncCallback() {
    @Override
    public void execute(String methodName, String params) {
        if (iWebviewBinder != null) {
            try {
                iWebviewBinder.handleJsFunc(methodName, params, new IWebviewBinderCallback.Stub() {
                    @Override
                    public void callJs(String params) throws RemoteException { //方法执行在子线程中
                        new Handler().post(new Runnable() {
                            @Override
                            public void run() { //在主线程中执行下面代码
                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                                    webView.evaluateJavascript(params, null);
                                } else {
                                    webView.loadUrl(params);
                                }
                            }
                        });
                    }
                });
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }
});
复制代码

以上就简单实现了进程间的数据通信,JS调用Java需要这样,但是对于Java调用JS只需要在子进程中实现就行了。

源码-您的Issues是我前进的动力,您的Star是我最大的鼓励,谢谢

WebviewComponent

你可能感兴趣的:(Webview独立进程并通过AIDL实现数据通信)