集成X5WebView内核主要是为了解决Android自带的WebView各种报错问题
研究了好几天,尝试过网上静态集成等等方法,没有一个正常的
后来在腾讯官方下载X5WebView最新SDK 2021-02-25的版本,但是官方Demo项目太老了,编译各种错误,无奈研究好久总算有点眉目,先说明下环境:
Android Studio 4.1.3
Visual studio 2019
Java 1.8
SDK Android API 28
NDK android-ndk-r21e
Cocos2d-x 3.17.2

腾讯浏览服务SDK,官方下载地址:https://x5.tencent.com/tbs/sdk.html
Cocos2d-x集成X5WebView分为两种
先说第一种:类集成,使用Activity来启动X5WebView

步骤1:
创建cocos2d-x项目
先创建一个cocos2d-x 3.17.2项目
使用Android studio 打开项目,同步可能报错,先把项目的插件版本和Gradle版本改为
3.5.3 对应Gradle版本 5.4.1



再设置NDK

设置完成以后项目会自动重新同步,若没有自动同步,请点击界面右上角的同步按钮同步项目
如图:
当项目显示可运行的时候,表示同步完成,项目可进行编译了

步骤2:
下载X5 SDK 引入jar包
https://x5.tencent.com/tbs/sdk.html
下载好后解压如图:

将tbs_sdk_thirdapp_v4.3.0.93_43993_sharewithdownloadwithfile_withoutGame_obfs_20210220_114728.jar复制到项目proj.android\app\libs目录下,没有libs文件夹自己创建

再打开Android studio界面,切换到Project样式



选择SDK文件右键Add As Library

直接确定,项目会自动同步完成

步骤3:
添加权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

Application节点添加 android:usesCleartextTraffic=“true”
解决高版本不能访问http问题,添加完成后如下:

步骤4:
参照官方Demo写一个继承WebView的类

创建名为X5WebView的类,代码如下:

package org.cocos2dx.cpp;import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;import com.tencent.smtt.sdk.WebSettings;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;public class X5WebView extends WebView
{//防止加载网页时调起系统浏览器private WebViewClient client = new WebViewClient() {public boolean shouldOverrideUrlLoading(WebView view, String url) {view.loadUrl(url);return true;}};//重写构造函数@SuppressLint("SetJavaScriptEnabled")public X5WebView(Context context, AttributeSet attributeSet) {super(context, attributeSet);this.setWebViewClient(client);WebSettings webSetting = this.getSettings();webSetting.setJavaScriptEnabled(true);webSetting.setJavaScriptCanOpenWindowsAutomatically(true);webSetting.setAllowFileAccess(true);webSetting.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);webSetting.setSupportZoom(true);webSetting.setBuiltInZoomControls(true);webSetting.setUseWideViewPort(true);webSetting.setSupportMultipleWindows(false);webSetting.setAppCacheEnabled(true);webSetting.setDomStorageEnabled(true);webSetting.setGeolocationEnabled(true);webSetting.setAppCacheMaxSize(Long.MAX_VALUE);webSetting.setPluginState(WebSettings.PluginState.ON_DEMAND);webSetting.setCacheMode(WebSettings.LOAD_NO_CACHE);this.getView().setClickable(true);}//重写构造函数public X5WebView(Context context) {super(context);this.setBackgroundColor(85621);}
}

实现WebViewJavaScriptFunction接口,好像调用JS要


代码如下:

package org.cocos2dx.cpp;public interface WebViewJavaScriptFunction {void onJsFunctionCalled(String tag);
}

步骤5:
在 AppActivity 类中添加一个全局变量,用来记录内核初始化状态
再添加X5内核初始化代码

public static boolean mX5WebViewInitState = false;  //用于记录内核是否初始化完成
package org.cocos2dx.cpp;import android.os.Bundle;
import org.cocos2dx.lib.Cocos2dxActivity;
import android.os.Build;
import android.util.Log;
import android.view.WindowManager;import com.tencent.smtt.sdk.QbSdk;public class AppActivity extends Cocos2dxActivity {public static boolean mX5WebViewInitState = false;  //用于记录内核是否初始化完成public static AppActivity mActivity;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.setEnableVirtualButton(false);super.onCreate(savedInstanceState);if (!isTaskRoot()) {return;}if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {WindowManager.LayoutParams lp = getWindow().getAttributes();lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;getWindow().setAttributes(lp);}mActivity = this;//初始化内核QbSdk.initX5Environment(getApplicationContext(), new QbSdk.PreInitCallback() {@Overridepublic void onCoreInitFinished() {Log.d("调试", "内核初始化完毕");mX5WebViewInitState = true;}@Overridepublic void onViewInitFinished(boolean b) {Log.d("调试", "WebView验证完毕,状态:" + b);mX5WebViewInitState = true;}});}}

再创建布局文件夹


再创建布局文件


创建好后如下图:

创建X5WebViewActivity类,用于显示X5WebView

package org.cocos2dx.cpp;import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;import com.snail.antifake.jni.EmulatorDetectUtil;
import com.tencent.smtt.export.external.interfaces.IX5WebChromeClient;
import com.tencent.smtt.export.external.interfaces.JsResult;
import com.tencent.smtt.sdk.CookieSyncManager;
import com.tencent.smtt.sdk.WebChromeClient;
import com.tencent.smtt.sdk.WebSettings;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;import cocos2dx.x5webview.com.R;public class X5WebViewActivity extends Activity
{private Context mContext;private Handler mHandle;private X5WebView mWebView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);  //去掉窗口标题getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);   //隐藏顶部的状态栏//如果不是模拟器才开启硬件加速,X5WebView内核模拟器开启硬件加速会报错闪退if(!EmulatorDetectUtil.isEmulator(X5WebViewActivity.this)) {getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);}setContentView(R.layout.layout_x5webview);mContext = this;//定时检测内核初始化状态mHandle = new Handler();mHandle.post(new Runnable() {@Overridepublic void run() {if(AppActivity.mX5WebViewInitState){mHandle.removeCallbacks(this);Log.d("调试", "内核初始化完成..");initX5WebView();return;}//延时调用runmHandle.postDelayed(this, 500);Log.d("调试", "内核初始化中..");}});}//初始化并创建 X5WebView,必须在内核初始化完成之后,否则X5WebView是无效的或是调用系统的WebView,通常情况下内核第一次初始化在20秒左右,第二次就很快private void initX5WebView(){mWebView = new X5WebView(mContext, null);// 创建布局文件FrameLayout layout = (FrameLayout) findViewById(android.R.id.content).getRootView();layout.setBackgroundColor(0);layout.addView(mWebView, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,FrameLayout.LayoutParams.MATCH_PARENT));mWebView.setWebViewClient(new WebViewClient() {@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {return false;}@Overridepublic void onPageFinished(WebView view, String url) {super.onPageFinished(view, url);}});mWebView.setWebChromeClient(new WebChromeClient() {@Overridepublic boolean onJsConfirm(WebView arg0, String arg1, String arg2,JsResult arg3) {return super.onJsConfirm(arg0, arg1, arg2, arg3);}View myVideoView;View myNormalView;IX5WebChromeClient.CustomViewCallback callback;/*** 全屏播放配置*/@Overridepublic void onShowCustomView(View view, IX5WebChromeClient.CustomViewCallback customViewCallback) {}@Overridepublic void onHideCustomView() {if (callback != null) {callback.onCustomViewHidden();callback = null;}if (myVideoView != null) {ViewGroup viewGroup = (ViewGroup) myVideoView.getParent();viewGroup.removeView(myVideoView);viewGroup.addView(myNormalView);}}@Overridepublic boolean onJsAlert(WebView arg0, String arg1, String arg2, JsResult arg3) {//这里写入你自定义的window alertreturn super.onJsAlert(null, arg1, arg2, arg3);}});WebSettings webSetting = mWebView.getSettings();webSetting.setAppCachePath(this.getDir("appcache", 0).getPath());webSetting.setDatabasePath(this.getDir("databases", 0).getPath());webSetting.setGeolocationDatabasePath(this.getDir("geolocation", 0).getPath());webSetting.setPluginState(WebSettings.PluginState.ON_DEMAND);CookieSyncManager.createInstance(mContext);CookieSyncManager.getInstance().sync();//打开网页mWebView.loadUrl("https://www.hao123.com");}@Overridepublic boolean onKeyUp(int keyCode, KeyEvent event) {//重写返回键事件if (keyCode == KeyEvent.KEYCODE_BACK) {if (mWebView != null && mWebView.canGoBack()) {mWebView.goBack();return true;} else {mWebView.destroy();this.finish();}return true;}return super.onKeyUp(keyCode, event);}
}

对上面的代码补充说明
//补充提示:检测模拟器 EmulatorDetectUtil类 需要引入 com.snail:antifake:1.4 依赖包

AndroidManifest添加配置

<activity
android:name="org.cocos2dx.cpp.X5WebViewActivity"
android:parentActivityName="org.cocos2dx.cpp.AppActivity"
android:theme="@android:style/Animation.Activity"
android:hardwareAccelerated="false"
android:screenOrientation="portrait">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.cocos2dx.cpp.AppActivity" />
</activity>

添加好后如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="cocos2dx.x5webview.com"android:installLocation="auto"><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.READ_PHONE_STATE" /><uses-feature android:glEsVersion="0x00020000" /><applicationandroid:label="@string/app_name"android:allowBackup="true"android:icon="@mipmap/ic_launcher"android:usesCleartextTraffic="true"><!-- Tell Cocos2dxActivity the name of our .so --><meta-data android:name="android.app.lib_name"android:value="MyGame" /><activityandroid:name="org.cocos2dx.cpp.AppActivity"android:screenOrientation="landscape"android:configChanges="orientation|keyboardHidden|screenSize"android:label="@string/app_name"android:theme="@android:style/Theme.NoTitleBar.Fullscreen"android:launchMode="singleTask"android:taskAffinity=""  ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><activityandroid:name="org.cocos2dx.cpp.X5WebViewActivity"android:parentActivityName="org.cocos2dx.cpp.AppActivity"android:theme="@android:style/Animation.Activity"android:hardwareAccelerated="false"android:screenOrientation="portrait"><meta-dataandroid:name="android.support.PARENT_ACTIVITY"android:value="org.cocos2dx.cpp.AppActivity" /></activity></application></manifest>

最后在AppActivity类中添加启动函数

public boolean createX5WebView(){Intent intent = new Intent(this, X5WebViewActivity.class);startActivity(intent);return true;}public static boolean createHTML5WebView(){return mActivity.createX5WebView(url);}

到此就完成了

下面只需要在cpp文件中添加JNI调用即可,其他细节自行实现

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)bool b = JniHelper::callStaticBooleanMethod("org/cocos2dx/cpp/AppActivity", "createHTML5WebView");if(!b){log("X5WebView浏览器创建失败,内核还未初始化完成");}
#endif
#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "cocos/platform/android/jni/JniHelper.h"
#endifUSING_NS_CC;Scene* HelloWorld::createScene()
{return HelloWorld::create();
}static void problemLoading(const char* filename)
{printf("Error while loading: %s\n", filename);printf("Depending on how you compiled you might have to add 'Resources/' in front of filenames in HelloWorldScene.cpp\n");
}bool HelloWorld::init()
{if ( !Scene::init() ){return false;}auto visibleSize = Director::getInstance()->getVisibleSize();Vec2 origin = Director::getInstance()->getVisibleOrigin();auto closeItem = MenuItemImage::create("CloseNormal.png","CloseSelected.png",CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));if (closeItem == nullptr ||closeItem->getContentSize().width <= 0 ||closeItem->getContentSize().height <= 0){problemLoading("'CloseNormal.png' and 'CloseSelected.png'");}else{float x = origin.x + visibleSize.width - closeItem->getContentSize().width/2;float y = origin.y + closeItem->getContentSize().height/2;closeItem->setPosition(Vec2(x,y));}// create menu, it's an autorelease objectauto menu = Menu::create(closeItem, NULL);menu->setPosition(Vec2::ZERO);this->addChild(menu, 1);auto label = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 24);if (label == nullptr){problemLoading("'fonts/Marker Felt.ttf'");}else{label->setPosition(Vec2(origin.x + visibleSize.width/2,origin.y + visibleSize.height - label->getContentSize().height));this->addChild(label, 1);}//打开浏览器按钮auto btn = MenuItemLabel::create(Label::createWithTTF("Open X5WebView Browser", "fonts/arial.ttf", 20),[this](Ref* pSender) {#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)JniHelper::callStaticBooleanMethod("org/cocos2dx/cpp/AppActivity", "createHTML5WebView");
#endif});btn->setPosition(Vec2(Director::getInstance()->getVisibleSize().width / 2, Director::getInstance()->getVisibleSize().height * 0.8f));menu->addChild(btn);return true;
}void HelloWorld::menuCloseCallback(Ref* pSender)
{Director::getInstance()->end();
}

可以看到,运行后Android studio调试输出



可以看到,现在可以播放视频了哈哈

2021-04-02 最新补充:
经过测试,cocos2d-x 3.17.2 使用 X5WebView内核时,在模拟器中闪退的原因已解决
在项目中的Gradle.properties中修改

PROP_APP_ABI=armeabi-v7a

PROP_APP_ABI=armeabi-v7a:arm64-v8a:x86

即可解决在打开页面时闪退,原来的硬件加速可设置为默认开启
将AndroidManifest.xml文件中的
android:hardwareAccelerated=“false”
改为
android:hardwareAccelerated=“true”

X5 Activity类中的

if(!EmulatorDetectUtil.isEmulator(X5WebViewActivity.this)) {getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
}

这条删掉即可,模拟器依然可以开启硬件加速

Cocos2d-x 3.17.2 集成X5WebView内核方法,完美运行相关推荐

  1. 【C语言爱心代码】不可思议!C语言仅仅用17行代码居然把爱心完美运行出来了

    最近很火电视剧李峋的爱心❤️代码,前段时间我也分享过HTML的爱心代码,相似度95%,后面也有不少小伙伴问我有没有其他语言的爱心代码,然后我翻出了半年前我学习C语言写的爱心代码例子,该源码简单,适合初 ...

  2. 驱动框架8——将驱动集成到内核中

    以下内容源于朱有鹏<物联网大讲堂>课程的学习整理,如有侵权,请告知删除. 十五.将驱动添加到内核中 1.驱动的存在形式 (1)野生,优势是方便调试开发,所以在开发阶段都是这种: (2)家养 ...

  3. Chrome浏览器上集成IE内核方案

    Chrome浏览器上集成IE内核方案 1. 架构图 双核功能的基本思路是,在chrome原有的render 管理的基础上,添加trident内核对象并在切换时将两个渲染的内核数据进行同步,进而将内核网 ...

  4. Linux Hook系统调用(适用基于x86_64的4.17.0以上的内核版本)

    随着rhel8.0于去年5月初发布以来,开启了rhel8.x的时代,随后一段时间里centos.oracle linux也都发布了基于rhel的8.x系统.前段时间我就安装了个centos8.0,但是 ...

  5. U-BOOT下使用bootm引导内核方法

    U-BOOT下使用bootm引导内核方法 注:   u-boot 使用的是打上: http://www.hhcn.com/cgi-bin/topic.cgi?forum=3&topic=651 ...

  6. linux下IPROTO_TCP,TCP/IP协议栈在Linux内核中的运行时序分析

    可选题目三:TCP/IP协议栈在Linux内核中的运行时序分析 在深入理解Linux内核任务调度(中断处理.softirg.tasklet.wq.内核线程等)机制的基础上,分析梳理send和recv过 ...

  7. 电脑卡顿不流畅怎么解决_使命召唤17画面卡顿怎么办-使命召唤17画面卡顿解决方法...

    使命召唤17画面卡顿怎么办?使命召唤17是一款备受许多玩家们喜爱的射击游戏,那么这款游戏内遇到卡顿情况要怎么办呢,接下来安卓市场小编为大家带来使命召唤17画面卡顿解决方法. 使命召唤17画面卡顿怎么办 ...

  8. 网站集成支付宝的方法和所需资料下载

    越来越多的网站想做网站集成支付宝功能,本文就详细的讲述一下网站集成支付宝的方法和所需资料下载. 一.网站集成支付宝学习流程建议(在本篇文档中,基本都可以找到相关资源下载) 1.阅读<支付宝接口集 ...

  9. Spring MVC集成Tiles使用方法

    Spring MVC集成Tiles使用方法 转载于:https://www.cnblogs.com/zhujiabin/p/5012129.html

  10. Linux内核编译和运行

    内核获取网站:https://www.kernel.org/pub/linux/kernel/ 步骤如下: 1.打开终端,更改用户权限为root.具体做法是在终端输入sudo su,然后按提示输入密码 ...

最新文章

  1. Google Colab——用谷歌免费GPU跑你的深度学习代码
  2. Datawhale赛事大满贯来了!
  3. Py之pandas:利用pandas工具输出每行的索引值、及其对应的行数据
  4. 奔跑吧,OpenStack现场分享:超融合架构如何抹平物理硬件差异?
  5. Convert Windows 32bit dirver to Windows 64bit
  6. if是什么c语言,这个C语言是什么(if(1))?
  7. 深井软岩巷道群支护技术与应用_黑龙江优质右旋锚杆厂家量大从优_双福煤矿支护架...
  8. 面试专题:Python面试题陷阱,你是否会中招?
  9. XML与HTML区别
  10. verycd下载资源
  11. Logistic模型预测人口增长
  12. 原生js预览ofd文件
  13. MIPS32-单周期数据通路设计
  14. 华为悦盒EC6108V9 、EC6108V9C_1080UI_非高安版_鸿蒙动画_免拆卡刷固件
  15. 【美味蟹堡王今日营业】论文学习笔记10-02
  16. C语言对复数模运算的处理
  17. spring cloud搭建教程
  18. iOS 开发 解决UICollectionView的多组头部视图样式不一样复用时发生错乱问题
  19. 三角形的几何公式大全_干货2020高中数学必备公式大全,吃透它们,数学再“捡”20分...
  20. 2023最新抖音取图小程序源码分享,带会员功能对接支付部署教程

热门文章

  1. 联通沃商店游戏中心接入规范(2014新版)
  2. 巨头不想再将“命脉”交给微信、支付宝
  3. Kaggle:Tabular Playground Series - May 2021
  4. Anaconda下载与安装详解
  5. abaqus算出来的转角单位是什么_ABAQUS中的单位制是如何规定的
  6. MES系统的功能详细以及应用价值介绍
  7. SonarQube代码审查工具
  8. 网络安全之渗透实战学习
  9. 常用地图经纬度转换,以及遇到的问题和解决方式
  10. 计算机网络第七版课后习题答案(第二章)(20210628)