美文网首页
笔记:WebView

笔记:WebView

作者: 盐海里的鱼 | 来源:发表于2020-12-06 23:06 被阅读0次
    Webview.png

    1.webview的组成由哪几部分组成

    答:由四个部分组成
    1.WebSettings 负责webview的设置部分
    2.WebViewClient 负责webview的生命周期回调
    3.WebViewChromeClient 与Js交互 以及内核部分调度 如弹出弹窗等
    4.JavaScriptInstance 负责js与native的交互部分

    2.为什么打造成组件以及如何实现的组件化?

    打造成组件是为了方便不同的项目导入,实现方法采用引入AutoService通过依赖倒置原则 由接口定义方法。

    定义接口与实现

    public interface IWebViewService {
        void startWebViewActivity(Context context, String url,String title,boolean isShowActionBar);
        Fragment getWebViewFragment(String url,boolean needNativeRefresh);
        void startLocalPage(Context context);
    }
    
    @AutoService({IWebViewService.class})
    public class WebViewServiceImpl  implements IWebViewService {
        @Override
        public void startWebViewActivity(Context context, String url, String title,boolean isShowActionBar) {
         ....
        }
    
        @Override
        public Fragment getWebViewFragment(String url,boolean needNativeRefresh) {
    `      ...
        }
    
        @Override
        public void startLocalPage(Context context) {
            ...
        }
    }
    
    

    找到组件,通过serviceLoader

    IWebViewService webImpl = ServiceLoader.load(IWebViewService.class).iterator().next();
    webImpl.startLocalPage(...)
    

    2.为什么要使用独立进程开启webview?

    1.webview本身占用的内存比较大 容易在性能较差的机型上导致oom
    2.webview需要兼容多种网页 新老网页格式都有 使用独立进程可以避免webview加载崩溃导致的app主进程崩溃引发crash

    3.进程之间的通信与调度你是如何处理的?

    不同进程之间的通信是通过实现aidl来完成的

    开启单独进程,在所在的activity下设置process属性
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.chenx.webview">
    
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <application android:usesCleartextTraffic="true">
            <activity android:name=".webviewprocess.WebViewActivity"
                android:process=":myWebView"
                android:theme="@style/Theme.AppCompat.Light.NoActionBar"></activity>
            <service android:name=".mainprocess.MainProcessCommandService"/>
        </application>
    
    </manifest>
    
    aidl创建与使用
    //创建
    // IWebviewProcessToMainProcess.aidl
    package com.chenx.webview;
    
    // Declare any non-default types here with import statements
    import com.chenx.webview.IMainProcessToWebviewProcessInterface;
    interface IWebviewProcessToMainProcess {
        void handleWebCommand(String commandName,String jsinParams,IMainProcessToWebviewProcessInterface callback);
    }
    //实现
    ... extends IWebviewProcessToMainProcess.Stub{
      @override
        void handleWebCommand(String commandName,String   jsinParams,IMainProcessToWebviewProcessInterface callback){
        }
    }
    
    Command命令定义
    public interface Command {
          //命令名称
         String name();
        //命令处理的行为
        void execute(Map parameters, IMainProcessToWebviewProcessInterface callback);
    }
    
    命令实现:
    @AutoService({Command.class})
    public class ToastCommand implements Command {
        @Override
        public String name() {
            return "showToast";
        }
    
        @Override
        public void execute(Map parameters, IMainProcessToWebviewProcessInterface callback) {
            Handler handler = new Handler(Looper.getMainLooper());
            handler.post(()->{
                Toast.makeText(BaseApplication.sApplication, String.valueOf(parameters.get("message")), Toast.LENGTH_SHORT).show();
            });
        }
    }
    
    调度器与分发器
    分发器
    public class WebViewProcessCommandDispatcher implements ServiceConnection {
        private static WebViewProcessCommandDispatcher sInstance;
        private IWebviewProcessToMainProcess iWebviewProcessToMainProcess;
        public static WebViewProcessCommandDispatcher getsInstance() {
           //获取分发器单例实例
            return sInstance;
        }
        //创建Aidl连接
        public void initAidlConnection(){
            Intent intent = new Intent(BaseApplication.sApplication, MainProcessCommandService.class);
            BaseApplication.sApplication.bindService(intent,this, Context.BIND_AUTO_CREATE);
        }
    
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder service) {
            iWebviewProcessToMainProcess = IWebviewProcessToMainProcess.Stub.asInterface(service);
        }
    
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            iWebviewProcessToMainProcess = null;
            initAidlConnection();
        }
    
        @Override
        public void onBindingDied(ComponentName name) {
            iWebviewProcessToMainProcess = null;
            initAidlConnection();
        }
        //处理命令分发给调度器
        public void executeCommand(String commandName, String params, BaseWebView webView){
            if(iWebviewProcessToMainProcess !=null){
                try {
                    //aidl实例 分发命令
                    iWebviewProcessToMainProcess.handleWebCommand(commandName, params,
                     new IMainProcessToWebviewProcessInterface.Stub() {
                        @Override
                        public void onResult(String callbackname, String response) throws RemoteException {
                            webView.handleCallback(callbackname, response);
                        }
                    });
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }else{
                Log.e(BaseWebView.TAG,"iWebviewProcessToMainProcess 未绑定===");
            }
        }
    

    调度器

    public class MainProcessCommandManager extends IWebviewProcessToMainProcess.Stub{
        private static final String TAG = "MainProcess";
        public static MainProcessCommandManager sInstance;
        private static Map<String, Command> mCommands = new HashMap<>();
    
        public static MainProcessCommandManager getInstance(){
            //调度器实例
            return sInstance;
        }
    
        public MainProcessCommandManager() {
            //自动注册命令
            ServiceLoader<Command> serviceLoader = ServiceLoader.load(Command.class);
            for (Command command:serviceLoader) {
                if(!mCommands.containsKey(command.name())){
                    mCommands.put(command.name(),command);
                }
            }
        }
        
        @Override
        public void handleWebCommand(String commandName, String jsinParams, IMainProcessToWebviewProcessInterface callback) throws RemoteException {
            //转map 调度命令
            executeCommand(commandName,new Gson().fromJson(jsinParams, Map.class),callback);
        }
    
        private void executeCommand(String commandName, Map params,IMainProcessToWebviewProcessInterface callback) {
            Log.d(TAG,"commandName:"+commandName);
              //执行命令
            mCommands.get(commandName).execute(params,callback);
        }
      }
    }
    
    回调
    通过回向aidl调用会webprocess
    iWebviewProcessToMainProcess.handleWebCommand(commandName, params, new IMainProcessToWebviewProcessInterface.Stub() {
                        @Override
                        public void onResult(String callbackname, String response) throws RemoteException {
                            Log.d("ResultNative","回传Native结果"+callbackname+"<"+response);
                            webView.handleCallback(callbackname, response);
                        }
                    });
    //调用evaluateJavascript注入js
    public void handleCallback(String callbackname, String response) {
            if(!TextUtils.isEmpty(callbackname)&&!TextUtils.isEmpty(response)){
                String jscode = "javascript:xiangxuejs.callback('"+callbackname+"',"+response+")";
                Log.d("callBackData",callbackname+":"+response);
                post(new Runnable() {
                    @Override
                    public void run() {
                        evaluateJavascript(jscode,null);
                    }
                });
            }
        }
    

    https://gitee.com/DaiMaZhiJia/WebViewDemoControler

    相关文章

      网友评论

          本文标题:笔记:WebView

          本文链接:https://www.haomeiwen.com/subject/kjnawktx.html