记录一个丑陋的BUG!!!
BUG说明:
项目对接ZegoGame 的H5游戏 需要对接游戏的H5.一些Android 和H5 交互需要相互效用....
噩梦开始了!!!
js 回调不通,后台一问三不知,产品不让我联系zego技术!!!!!日了狗了
问题说明:



参考截图
- Android端的Js配置和H5的Js调用对不上(H5没按照文档写)
解决思路
Js 注入覆盖或者修改H5的Js方法
1:WebView 配置
核心方法
- settings.setJavaScriptEnabled(true); 开启Js桥
- webView.addJavascriptInterface(new GameJsBridge(this), "app"); 注册回调内容
- onPageFinished () 页面加载完成
typescript
private WebView initWebView() {
webView.setBackgroundColor(Color.TRANSPARENT);
//update webview settings
WebSettings settings = webView.getSettings();
settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
settings.setBuiltInZoomControls(true);
settings.setJavaScriptEnabled(true);
settings.setDatabaseEnabled(true);
settings.setDomStorageEnabled(true);
//set webview client
webView.setWebChromeClient(new WebChromeClient());
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
Log.d(TAG, "onPageStarted");
}
@Override
public void onPageFinished(WebView view, String url) {
Log.d(TAG, "onPageFinished");
webView.evaluateJavascript(
"(function() { " +
" var originPostMessage = window.top.postMessage;" +
" window.top.postMessage = function(data) { " +
" var msg = (typeof data === 'string') ? data : JSON.stringify(data);" +
" if(window.app && window.app.postMessage) {" +
" window.app.postMessage(msg);" +
" }" +
" if(originPostMessage) {" +
" originPostMessage.call(window.top, data, '*');" +
" }" +
" };" +
"})();",
null
);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
String outUrl = request.getUrl().toString();
view.loadUrl(outUrl);
return true;
}
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
Log.d(TAG, "onReceivedError: " + error);
}
});
//add jsb
webView.addJavascriptInterface(new GameJsBridge(this), "app");
webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
return webView;
}
1:Js回调桥配置
typescript
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.JavascriptInterface;
import com.google.gson.Gson;
import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;
import es.dmoral.toasty.Toasty;
public class GameJsBridge {
private static final String TAG = "Zego游戏";
private final Context context;
public GameJsBridge(@NotNull Context context) {
this.context = context;
}
private JSONObject parseMsg(@NotNull String message) {
try {
return new JSONObject(message);
} catch (JSONException e) {
return null;
}
}
@JavascriptInterface
public void postMessage(String message) {
Log.e(TAG, "postMessage: " + message);
if (TextUtils.isEmpty(message)) return;
try{
JSONObject schemeInfo = parseMsg(message);
if (schemeInfo == null) return;
//'{"cid":"TO_CHARGE","params":{}
String cid = schemeInfo.optString("cid");
JSONObject params = schemeInfo.optJSONObject("params");
if ("TO_CHARGE".equals(cid)) {
// 支付
} else if ("CLOSE_COCOS_VIEW".equals(cid)) {
// 关闭全屏游戏
if(context!=null&& context instanceof Activity)
((Activity)context).finish();
} else if ("NOTIFY_GAME_STATUS".equals(cid)) {
if (params.optInt("status") == 4) {
// 🇺🇸en: When the game is settled, notify the client to refresh the balance displayed on the client
Toasty.normal(context, "complete").show();
}
}
}catch (Exception e){
}
}
}
3.注入Js 代码
- 在浏览器sources 中ctrl +shift+f 查找 GameJsBridge 中的postMessage

说明: H5 调用Js 调用的是
- window.top.postMessage()
- window.WTChannel.postMessage()
根据GameJsBridge 获取的是 cid 和 params
ini
String cid = schemeInfo.optString("cid");
JSONObject params = schemeInfo.optJSONObject("params");
Js 代码注入 核心代码:
typescript
public void onPageFinished(WebView view, String url) {
Log.d(TAG, "onPageFinished");
webView.evaluateJavascript(
"(function() { " +
" var originPostMessage = window.top.postMessage;" +
" window.top.postMessage = function(data) { " +
" var msg = (typeof data === 'string') ? data : JSON.stringify(data);" +
" if(window.app && window.app.postMessage) {" +
" window.app.postMessage(msg);" +
" }" +
" if(originPostMessage) {" +
" originPostMessage.call(window.top, data, '*');" +
" }" +
" };" +
"})();",
null
);
}
总结
当H5页面为三方或者外包的代码,时不时就会出现这种情况,所以移动端要想和他们撕逼.最好具备查询这种问题的能力.
- 定位能力
- 注入修改能力