美文网首页WebView交互
【Android Web】腾讯X5浏览器的集成与常见问题

【Android Web】腾讯X5浏览器的集成与常见问题

作者: 欢子3824 | 来源:发表于2018-07-28 15:26 被阅读0次

    前言

    近年来,混合开发也越来越用的更多,而原生webview的各种坑,比如说 上传图片、文件问题、视频全屏问题(什么在微信上打开都是好的,你这怎么全屏不了)、版本差异问题,所以还是建议使用腾讯x5浏览器。

    如何使用

    • 1.去官网上下载最新的jar、so文件等 链接点这里
    • 2.添加jar包、so文件,配置gradle


      QQ截图20180728102235.png

      在build.gradle 中添加libs、配置ndk

     sourceSets {
            main {
                jniLibs.srcDirs = ['libs']
            }
        }
    
      ndk {
                abiFilters "armeabi"
            }
    
    • 3.在Application中添加初始化x5代码,记得在AndroidManifest.xml中注册你自定的Application
      QbSdk.PreInitCallback cb = new QbSdk.PreInitCallback() {
    
                @Override
                public void onViewInitFinished(boolean arg0) {
                    //x5內核初始化完成的回调,为true表示x5内核加载成功,否则表示x5内核加载失败,会自动切换到系统内核。
                    Log.d("app", " onViewInitFinished is " + arg0);
                }
    
                @Override
                public void onCoreInitFinished() {
                }
            };
            //x5内核初始化接口
            QbSdk.initX5Environment(getApplicationContext(), cb);
    
    • 4.添加权限
    
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.READ_PHONE_STATE" />
        <uses-permission android:name="android.permission.READ_SETTINGS" />
        <uses-permission android:name="android.permission.WRITE_SETTINGS" />
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    
        <!-- 硬件加速对X5视频播放非常重要,建议开启 -->
        <uses-permission android:name="android.permission.GET_TASKS" />
    
    • 5.添加WebActivity,初始化x5配置 记得在AndroidManifest.xml中注册
            webView = (WebView) findViewById(R.id.webView);
            WebSettings webSetting = webView.getSettings();
            webSetting.setJavaScriptEnabled(true);
            webSetting.setJavaScriptCanOpenWindowsAutomatically(true);
            webSetting.setAllowFileAccess(true);
            webSetting.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
            webSetting.setSupportZoom(true);
            webSetting.setBuiltInZoomControls(false);
            webSetting.setUseWideViewPort(true);
            webSetting.setSupportMultipleWindows(true);
            // webSetting.setLoadWithOverviewMode(true);
            webSetting.setAppCacheEnabled(true);
            // webSetting.setDatabaseEnabled(true);
            webSetting.setDomStorageEnabled(true);
            webSetting.setGeolocationEnabled(true);
            webSetting.setAppCacheMaxSize(Long.MAX_VALUE);
            // webSetting.setPageCacheCapacity(IX5WebSettings.DEFAULT_CACHE_CAPACITY);
            webSetting.setPluginState(WebSettings.PluginState.ON_DEMAND);
            // webSetting.setRenderPriority(WebSettings.RenderPriority.HIGH);
            webSetting.setCacheMode(WebSettings.LOAD_NO_CACHE);
    
            getWindow().setFormat(PixelFormat.TRANSLUCENT);
    
            webView.getView().setOverScrollMode(View.OVER_SCROLL_ALWAYS);
    
            // this.getSettingsExtension().setPageCacheCapacity(IX5WebSettings.DEFAULT_CACHE_CAPACITY);//extension
            // settings 的设计
            webView.setWebViewClient(new WebViewClient() {
                @Override
                public boolean shouldOverrideUrlLoading(WebView webView, String url) {
                    webView.loadUrl(url);
                    return true;
                }
            });
    
    • 6、添加上传文件、图片适配代码
      webView.setWebChromeClient(new WebChromeClient() {
    
    
                // For Android 3.0+
                public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
                    uploadFile = uploadFile;
                    openFileChooseProcess();
                }
    
                // For Android < 3.0
                public void openFileChooser(ValueCallback<Uri> uploadMsgs) {
                    uploadFile = uploadFile;
                    openFileChooseProcess();
                }
    
                // For Android  > 4.1.1
                public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
                    uploadFile = uploadFile;
                    openFileChooseProcess();
                }
    
                // For Android  >= 5.0
                public boolean onShowFileChooser(com.tencent.smtt.sdk.WebView webView,
                                                 ValueCallback<Uri[]> filePathCallback,
                                                 WebChromeClient.FileChooserParams fileChooserParams) {
                    uploadFiles = filePathCallback;
                    openFileChooseProcess();
                    return true;
                }
    
            });
    
    
        private void openFileChooseProcess() {
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
            i.setType("*/*");
            startActivityForResult(Intent.createChooser(i, "test"), 0);
        }
    
    
    • 7、处理选择文件、图片后回调
     @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
    
            if (resultCode == RESULT_OK) {
                switch (requestCode) {
                    case 0:
                        if (null != uploadFile) {
                            Uri result = data == null || resultCode != RESULT_OK ? null
                                    : data.getData();
                            uploadFile.onReceiveValue(result);
                            uploadFile = null;
                        }
                        if (null != uploadFiles) {
                            Uri result = data == null || resultCode != RESULT_OK ? null
                                    : data.getData();
                            uploadFiles.onReceiveValue(new Uri[]{result});
                            uploadFiles = null;
                        }
                        break;
                    default:
                        break;
                }
            } else if (resultCode == RESULT_CANCELED) {
                if (null != uploadFile) {
                    uploadFile.onReceiveValue(null);
                    uploadFile = null;
                }
    
            }
        }
    
    • 8、添加视频全屏相关代码
    
            webView.setWebChromeClient(new WebChromeClient() {
    
    
                // For Android 3.0+
                public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
                    uploadFile = uploadFile;
                    openFileChooseProcess();
                }
    
                // For Android < 3.0
                public void openFileChooser(ValueCallback<Uri> uploadMsgs) {
                    uploadFile = uploadFile;
                    openFileChooseProcess();
                }
    
                // For Android  > 4.1.1
                public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
                    uploadFile = uploadFile;
                    openFileChooseProcess();
                }
    
                // For Android  >= 5.0
                public boolean onShowFileChooser(com.tencent.smtt.sdk.WebView webView,
                                                 ValueCallback<Uri[]> filePathCallback,
                                                 WebChromeClient.FileChooserParams fileChooserParams) {
                    uploadFiles = filePathCallback;
                    openFileChooseProcess();
                    return true;
                }
    
                View myVideoView;
                View myNormalView;
                IX5WebChromeClient.CustomViewCallback callback;
    
    
                /**
                 * 全屏播放配置
                 */
                @Override
                public void onShowCustomView(View view,
                                             IX5WebChromeClient.CustomViewCallback customViewCallback) {
                    FrameLayout normalView = (FrameLayout) findViewById(R.id.web_filechooser);
                    ViewGroup viewGroup = (ViewGroup) normalView.getParent();
                    viewGroup.removeView(normalView);
                    viewGroup.addView(view);
                    myVideoView = view;
                    myNormalView = normalView;
                    callback = customViewCallback;
                }
    
                @Override
                public void onHideCustomView() {
                    if (callback != null) {
                        callback.onCustomViewHidden();
                        callback = null;
                    }
                    if (myVideoView != null) {
                        ViewGroup viewGroup = (ViewGroup) myVideoView.getParent();
                        viewGroup.removeView(myVideoView);
                        viewGroup.addView(myNormalView);
                    }
                }
    
            });
    
     webView.addJavascriptInterface(new WebViewJavaScriptFunction() {
    
                @Override
                public void onJsFunctionCalled(String tag) {
    
                }
    
                @JavascriptInterface
                public void onX5ButtonClicked() {
                    enableX5FullscreenFunc();
                }
    
                @JavascriptInterface
                public void onCustomButtonClicked() {
                    disableX5FullscreenFunc();
                }
    
                @JavascriptInterface
                public void onLiteWndButtonClicked() {
                    enableLiteWndFunc();
                }
    
                @JavascriptInterface
                public void onPageVideoClicked() {
                    enablePageVideoFunc();
                }
            }, "Android");
    
      // 向webview发出信息
        private void enableX5FullscreenFunc() {
    
            if (webView.getX5WebViewExtension() != null) {
                Bundle data = new Bundle();
    
                data.putBoolean("standardFullScreen", false);// true表示标准全屏,false表示X5全屏;不设置默认false,
    
                data.putBoolean("supportLiteWnd", false);// false:关闭小窗;true:开启小窗;不设置默认true,
    
                data.putInt("DefaultVideoScreen", 2);// 1:以页面内开始播放,2:以全屏开始播放;不设置默认:1
    
                webView.getX5WebViewExtension().invokeMiscMethod("setVideoParams",
                        data);
            }
        }
    
        private void disableX5FullscreenFunc() {
            if (webView.getX5WebViewExtension() != null) {
                Bundle data = new Bundle();
    
                data.putBoolean("standardFullScreen", true);// true表示标准全屏,会调起onShowCustomView(),false表示X5全屏;不设置默认false,
    
                data.putBoolean("supportLiteWnd", false);// false:关闭小窗;true:开启小窗;不设置默认true,
    
                data.putInt("DefaultVideoScreen", 2);// 1:以页面内开始播放,2:以全屏开始播放;不设置默认:1
    
                webView.getX5WebViewExtension().invokeMiscMethod("setVideoParams",
                        data);
            }
        }
    
        private void enableLiteWndFunc() {
            if (webView.getX5WebViewExtension() != null) {
                Bundle data = new Bundle();
    
                data.putBoolean("standardFullScreen", false);// true表示标准全屏,会调起onShowCustomView(),false表示X5全屏;不设置默认false,
    
                data.putBoolean("supportLiteWnd", true);// false:关闭小窗;true:开启小窗;不设置默认true,
    
                data.putInt("DefaultVideoScreen", 2);// 1:以页面内开始播放,2:以全屏开始播放;不设置默认:1
    
                webView.getX5WebViewExtension().invokeMiscMethod("setVideoParams",
                        data);
            }
        }
    
        private void enablePageVideoFunc() {
            if (webView.getX5WebViewExtension() != null) {
                Bundle data = new Bundle();
    
                data.putBoolean("standardFullScreen", false);// true表示标准全屏,会调起onShowCustomView(),false表示X5全屏;不设置默认false,
    
                data.putBoolean("supportLiteWnd", false);// false:关闭小窗;true:开启小窗;不设置默认true,
    
                data.putInt("DefaultVideoScreen", 1);// 1:以页面内开始播放,2:以全屏开始播放;不设置默认:1
    
                webView.getX5WebViewExtension().invokeMiscMethod("setVideoParams",
                        data);
            }
        }
    
    • 9、添加下载相关代码
     webView.setDownloadListener(new DownloadListener() {
                @Override
                public void onDownloadStart(String s, String s1, String s2, String s3, long l) {
    
                }
            });
    
    • 10、最后,当Activity销毁时,释放webview
     /**
         * 确保注销配置能够被释放
         */
        @Override
        protected void onDestroy() {
            if (this.webView != null) {
                webView.destroy();
            }
            super.onDestroy();
        }
    

    到这里,x5浏览器的集成已经完成了,快去试试吧

    常见问题

    1.视频无法全屏
    请注意AndroidManifest.xml 中配置

     <activity
                android:name=".WebActivity"
                android:configChanges="orientation|screenSize|keyboardHidden"></activity>
    

    2.原生与webview 共享cookie
    首先,原生需要将cookie 持久化的保存起来,具体可以参考 【Android架构】基于MVP模式的Retrofit2+RXjava封装之常见问题(四),至于非okhttp网络的,可以自行百度
    然后传递给webview

          //创建CookieSyncManager
            CookieSyncManager.createInstance(context);
            //得到CookieManager
            CookieManager cookieManager = CookieManager.getInstance();
            cookieManager.setAcceptCookie(true);
            cookieManager.removeSessionCookie();// 移除
            cookieManager.removeAllCookie();
            //得到向URL中添加的Cookie的值
            store = new PersistentCookieStore(context);
            List<Cookie> cookieList = store.getCookies();
            if (cookieList != null && cookieList.size() > 0) {
                Cookie cookie = null;
             for (Cookie c : cookieList) {
                    if (c.domain() != null) {
                        if (c.domain().contains("38")) {
                            cookie = c;
                        }
                    }
                }
                if (cookie == null) {
                    cookie = cookieList.get(0);
                }
    
    
                cookieManager.setCookie(url, cookie.name() + "=" + cookie.value());
              if (Build.VERSION.SDK_INT < 21) {
                    CookieSyncManager.getInstance().sync();
                } else {
                    CookieManager.getInstance().flush();
                }
            }
    

    需要注意的是,本地保存的cookie可能会有多个,要根据domain 来判断出正确的cookie

    相关文章

      网友评论

        本文标题:【Android Web】腾讯X5浏览器的集成与常见问题

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