cocos2d / cocos2d-x

Cocos2d-x is a suite of open-source, cross-platform, game-development tools utilized by millions of developers across the globe. Its core has evolved to serve as the foundation for Cocos Creator 1.x & 2.x.
https://www.cocos.com/en/cocos2d-x
18.22k stars 7.06k forks source link

【 Bad code found 】【RESOLVED】Version 3.17.2 got crash on Android, once add a WebView in scene, and then tap back button(device) #20586

Open liuyi opened 4 years ago

liuyi commented 4 years ago

Steps to Reproduce:

  1. Create an empty project by cocos command: cocos hello -p com.test.hello -l js
  2. Open app.js and add a method to append a webview in stage, code like below:

`testWeb:function(){ var _self=this; var rect = cc.visibleRect;

        var webView = new ccui.WebView();

        webView.setContentSize(rect.width, rect.height);
        webView.setJavascriptInterfaceScheme("ddschool");
        webView.width = rect.width;
        webView.height = rect.height;
        webView.anchorX = 0;
        webView.anchorY = 0;
        webView.x = rect.bottomLeft.x;
        webView.y = rect.bottomLeft.y;
        webView.loadURL('http://www.baidu.com');
        // webView.loadURL('http://dev.ddkids.com/web/back_demo.html');
        webView.setScalesPageToFit(true);
        console.log("load page>>>>>>>>>>>>>>")

        this.addChild(webView);
        setTimeout(function () {
            webView.removeFromParent(true);
             console.log("remove page-------------")
        },60000);

}`

  1. Tap the back button of device, or slide in from right side on infinity display phone.

    • some devices will crash (The cocos activity has be killed) at this step.
  2. after a while, the webview removed, do step 3.

    • the device will crash (The cocos activity has be killed)

Found a same post at:https://github.com/cocos2d/cocos2d-x/issues/20521

Another post with a solution(NOT TOO GOOD ,BUT WORKS): https://github.com/cocos2d/cocos2d-x/pull/18153

liuyi commented 4 years ago

At Cocos2dxWebView.java,this.setFocusableInTouchMode(true); This line will cause the app crash on android with cocos2dx 3.17.2

liuyi commented 4 years ago

Finally, I resolved this issue. The reason is that Cocos2dxGLSurfaceView haven't get focus when WebView removed from stage or hidden.

How to fix:

public static void removeWebView(final int index) { sCocos2dxActivity.runOnUiThread(new Runnable() { @Override public void run() { Cocos2dxWebView webView = webViews.get(index); if (webView != null) { webViews.remove(index); sLayout.removeView(webView); }

            //add this code to fix focus issue
            boolean isHaveVisibleWebView = false;
            for (int i = 0; i < webViews.size(); i++) {
                if (webViews.get(i).getVisibility() == View.VISIBLE) {
                    isHaveVisibleWebView = true;
                    break;
                }
            }
            if (!isHaveVisibleWebView) {
                Cocos2dxGLSurfaceView.getInstance().requestFocus();
            }
        }
    });
}

public static void setVisible(final int index, final boolean visible) {
    sCocos2dxActivity.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            Cocos2dxWebView webView = webViews.get(index);
            if (webView != null) {
                webView.setVisibility(visible ? View.VISIBLE : View.GONE);
            }

           //add this code to fix focus issue
            if(webView.getVisibility()==View.GONE){
                Cocos2dxGLSurfaceView.getInstance().requestFocus();
            }
        }
    });
}