Android使用腾讯x5web内核的离线内核

2,900 阅读4分钟

使用腾讯x5web内核的离线内核

官网地址:x5.tencent.com

一、使用背景:

  • 1.最初的时候使用x5web-sdk是为了适配Android5.1.1-Padwebview加载前端页面的问题。(使用普通的webview加载vue前端页面出不来)
  • 2.使用x5web内核是为了解决webview加载前端页面的样式问题。(使用x5web内核之前加载的前端页面样式会有问题)
  • 3.使用x5web离线内核是为了解决:在内网环境下使用到x5web内核。(因为我们的应用是在定制的Pad上面在内网环境下使用的,所以在线加载内核的方法不可用)
1.x5web-sdk使用:
  • 1.引入tbs_sdk_xxx.jar依赖
  • 2.替换WebViewX5WebView
    import com.tencent.smtt.sdk.WebSettings;
    import com.tencent.smtt.sdk.WebSettings.LayoutAlgorithm;
    import com.tencent.smtt.sdk.WebView;
    import com.tencent.smtt.sdk.WebViewClient;
    
    public class X5WebView extends WebView {...}
    

x5web内核使用1.png

2.在线x5web内核使用:
  • 1.进入APP后判断x5web内核是否可用。可用直接进入,不可用先执行下载再重新进入APP(因为下载的资源有40M左右所以加了一个进度提示来告诉用户下载的情况)
    public void onCreate(){
        Boolean canUseTbs = initQbSdk();
        if (!canUseTbs) return;
    }
    
    public boolean initQbSdk() {
        Boolean canLoad = QbSdk.canLoadX5(this);
        if (canLoad) return true;
        holder.setProgressLayoutShow();
        Log.d("app", "WelcomeActivity---initQbSdk");
        // 在调用TBS初始化、创建WebView之前进行如下配置
        HashMap map = new HashMap();
        map.put(TbsCoreSettings.TBS_SETTINGS_USE_SPEEDY_CLASSLOADER, true);
        map.put(TbsCoreSettings.TBS_SETTINGS_USE_DEXLOADER_SERVICE, true);
        QbSdk.initTbsSettings(map);
        //配置使用4G网
        QbSdk.setDownloadWithoutWifi(true);
        QbSdk.disableAutoCreateX5Webview();
        QbSdk.setTbsListener(new TbsListener() {
            @Override
            public void onDownloadFinish(int progress) {
                Log.d("app", "onDownloadFinish -->下载X5内核完成:" + progress);
            }
    
            @Override
            public void onInstallFinish(int i) {
                Log.d("app", "onInstallFinish -->安装X5内核进度:" + i);
            }
    
            @Override
            public void onDownloadProgress(int progress) {
                Log.d("app", "onDownloadProgress -->下载X5内核进度:" + progress);
                holder.setProgress(progress);
            }
        });
        //搜集本地tbs内核信息并上报服务器,服务器返回结果决定使用哪个内核。
        //x5内核初始化接口
        QbSdk.initX5Environment(getApplicationContext(), new QbSdk.PreInitCallback() {
    
            @Override
            public void onViewInitFinished(boolean arg0) {
                // TODO Auto-generated method stub
                //x5內核初始化完成的回调,为true表示x5内核加载成功,否则表示x5内核加载失败,会自动切换到系统内核。
                Log.d("app", " onViewInitFinished is " + arg0);
                if (!arg0) {//加载失败
                    DialogUtil.showDialog(WelcomeActivity.this, "提示", "X5Web内核加载失败,请切换至公网环境下载!", false, "", null, "", null, "重试", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            QbSdk.clearAllWebViewCache(WelcomeActivity.this.getApplicationContext(), true);
                            QbSdk.reset(WelcomeActivity.this.getApplicationContext());
                            QbSdk.resetDecoupleCore(WelcomeActivity.this.getApplicationContext());
                            TbsDownloader.startDownload(WelcomeActivity.this);
                            dialogInterface.dismiss();
                        }
                    });
                } else {//加载成功
                    DialogUtil.showDialog(WelcomeActivity.this, "提示", "X5Web内核加载成功,请切换至内网使用!", false, "", null, "", null, "确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            AppExitUtils.exitWithNoToast(WelcomeActivity.this, true);
                            dialogInterface.dismiss();
                        }
                    });
                }
            }
    
            @Override
            public void onCoreInitFinished() {
                Log.d("app", " onCoreInitFinished is ");
                // TODO Auto-generated method stub
            }
        });
        Log.i("app", "app是否主动禁用了X5内核: " + QbSdk.getIsSysWebViewForcedByOuter());
        return false;
    }
    

二、x5web离线内核使用过程:

上面的在线内核解决了X5WebView加载前端页面的样式问题。

因为要在内网环境下使用,还要使用离线内核。官网现在已经不支持离线内核的使用, 所以只能在网上找找。

x5web内核使用2.png

试了几种之后,找到一个靠谱的方法TBS文件浏览自主安装内核方案

使用上面的方法可以安装内核离线包,并且使用其内核。

这里需要注意的是:

  • 根据自己的手机内核版本安装特定版本的内核包。我这里的Pad的内核是arm64-v8a的,所以使用的内核包版本也是64的。
  • x5web-sdk安装内核包方法需要特定版本的sdk,我这里使用的是tbs_sdk_thirdapp_v4.3.0.253_44153xxx.jar
  • x5web-sdkx5.64.apk可以在下面看到,可以直接下载使用。

1.使用流程:

  • 1.引入 tbs_sdk_v4.3.0.253.jar 包到项目
  • 2.将 x5.tbs.org.64.apk 放到assets目录下
  • 3.修改应用级别的build.gradle文件
    android {...
        defaultConfig {...
            ndk {
                abiFilters "arm64-v8a"
            }
        }
    }
    
  • 4.复制assets目录的安装包到手机内存卡中代码:
    public class X5WebUtils {
        public static String APK_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/ceitsa/x5.tbs.org.64.apk";
    
        // 将assets目录下的文件拷贝出来
        public static boolean exportAPK2Phone(Context context) {
            File file = null;
            try {
                // 目录存在,则将apk中raw中的需要的文档复制到该目录下
                file = new File(APK_PATH);
                if (!file.getParentFile().exists()) {
                    file.getParentFile().mkdirs();
                }
                if (!file.exists()) {// 文件不存在
                    System.out.println("要打开的文件不存在");
                    InputStream ins = context.getResources().getAssets().open("x5.tbs.org.64.apk");
                    System.out.println("开始读入");
                    FileOutputStream fos = new FileOutputStream(file);
                    System.out.println("开始写出");
                    byte[] buffer = new byte[8192];
                    int count = 0;// 循环写出
                    while ((count = ins.read(buffer)) > 0) {
                        fos.write(buffer, 0, count);
                    }
                    System.out.println("已经创建该文件");
                    fos.close();// 关闭流
                    ins.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (file != null && file.exists()) {
                return true;
            }
            return false;
        }
    }
    
  • 5.安装离线x5web内核代码:
    public void viewParam(){
        Boolean canUseTbs = initQbSdkOffLine();
        if (!canUseTbs) return;
        ......
    }
    
    public boolean initQbSdkOffLine() {
        int version = android.os.Build.VERSION.SDK_INT;
        Log.d("app", "initQbSdkOffLine=version>>" + version);
        if (version > 22) return true;
        Boolean canLoad = QbSdk.canLoadX5(getApplicationContext());
        if (canLoad) return true;
        Log.d("app", "initQbSdkOffLine=canLoad>>" + canLoad);
    
        final CustomProgressDialog dialog = DialogUtil.showLoadingDialog(this, "加载X5Web内核中...", false, false);
        Boolean exportRes = X5WebUtils.exportAPK2Phone(this);
        Log.d("app", "initQbSdkOffLine=exportRes>>" + exportRes);
        QbSdk.reset(getApplicationContext());
        QbSdk.installLocalTbsCore(getApplicationContext(), 45912, X5WebUtils.APK_PATH);
        QbSdk.initX5Environment(getApplicationContext(), new QbSdk.PreInitCallback() {
    
            @Override
            public void onViewInitFinished(boolean arg0) {
                // TODO Auto-generated method stub
                Log.d("app", " onViewInitFinished is " + arg0);
                dialog.dismiss();
                if (arg0) {
                    Toast toast = Toast.makeText(NmApplication.getInstance().getCurrentFragmentActivity(), "X5Web内核加载完成!", Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                    toast.show();
                    viewParam();
                }
            }
    
            @Override
            public void onCoreInitFinished() {
                Log.d("app", " onCoreInitFinished is ");
            }
        });
        return false;
    }