Webview獨立程式並通過AIDL實現資料通訊

風清袖一發表於2018-09-26

前言:簡單寫下,目前程式碼也很粗糙

思路

多程式資料通訊

步驟

實現獨立程式

在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

相關文章