[ 找到了引擎出错代码问题所在 ,自己解决了!!!] 严重引擎BUG ,安卓空项目 ,创建一个 WEBVIEW ,点击后退按钮 ,APP崩溃。

如何实现:
1、使用cocos2dx 3.17.2版本,创建一个最简单的JS工程。
2、在app.js里创建一个webview,然后随便打开一个网页。最简单的空网页都可以。
3、点返回按钮,如果是全面屏则是从右侧屏幕边缘划入。
4、某些手机,多试步骤3几次,崩溃;某些手机需要关闭webview后,再试步骤3,必死。

@panda 请引擎组同学帮忙看看吧?
因为我们是从一开始就使用的cocos2djs版本的项目, 这次终于没有忍耐住,将版本升到了3.17.2(之前是3.15.1)。
因为这个问题,导致项目只能回撤到老版本。

另外,不用creator的原因就是:我们的工具链和代码库都是基于cocos2djs开发的,且是做原生APP,暂时没可能切换到creator.

问题原因:
该问题是由于WebView被移除或隐藏时,Cocos2dxGLSurfaceView没有及时获得焦点,导致被系统杀掉。

解决方案:

修改Cocos2dxWebViewHelper.java的两个方法:
removeWebView和setVisible:

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);
}

            // 修复WebView销毁之后点击返回键崩溃的bug 这段来自于 https://forum.cocos.org/t/cocos2d-x-webview/93592
            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);
            }
            //下面代码就是修复问题的关键
            if(webView.getVisibility()==View.GONE){
                Cocos2dxGLSurfaceView.getInstance().requestFocus();
            }
        }
    });
}

这里是出BUG代码,创建项目的helloword app.js:
/****************************************************************************
Copyright © 2017-2018 Xiamen Yaji Software Co., Ltd.

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/

var HelloWorldLayer = cc.Layer.extend({
sprite:null,
ctor:function () {
//////////////////////////////
// 1. super init first
this._super();

    /////////////////////////////
    // 2. add a menu item with "X" image, which is clicked to quit the program
    //    you may modify it.
    // ask the window size
    var size = cc.winSize;

    /////////////////////////////
    // 3. add your codes below...
    // add a label shows "Hello World"
    // create and initialize a label
    var helloLabel = new cc.LabelTTF("Hello World", "Arial", 38);
    // position the label on the center of the screen
    helloLabel.x = size.width / 2;
    helloLabel.y = size.height / 2 + 200;
    // add the label as a child to this layer
    this.addChild(helloLabel, 5);

    // add "HelloWorld" splash screen"
    this.sprite = new cc.Sprite(res.HelloWorld_png);
    this.sprite.attr({
        x: size.width / 2,
        y: size.height / 2
    });
    this.addChild(this.sprite, 0);

    this.testWeb();

    return true;
},
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);
}

});

var HelloWorldScene = cc.Scene.extend({
onEnter:function () {
this._super();
var layer = new HelloWorldLayer();
this.addChild(layer);
}
});

找到了问题所在:
在Cocos2dxWebView.java里,this.setFocusableInTouchMode(true);//开启焦点,这个将导致在3.17.2上按后退键崩溃。
请问引擎组老大们,这个要如何修复呢?@panda

找到了一个跟我同样问题的帖子,他给出的第二种方案实测在当前版本里无法使用,但是也可以作为一个参考:

在他的基础上,再修改一下就可以用了:

修改 Cocos2dxWebViewHelper.java 的setVisible方法

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);
}
if(webView.getVisibility()==View.GONE){
Cocos2dxGLSurfaceView.getInstance().requestFocus();//如果网页隐藏也要获取一次焦点。
}
}
});
}

@ourbrander 大佬,我这改了还是没效果啊。依旧会闪退

你可以断点 看看具体闪退在哪里。不一定是我描述的这个问题呢~ 多打断点吧。另外,android studio C++也可以断点。 应该比较方便调试的