【问题标题】:issue with webview and Ti.App.addEventListener causing crashwebview 和 Ti.App.addEventListener 导致崩溃的问题
【发布时间】:2015-04-12 19:00:33
【问题描述】:

请原谅这里的丑陋代码就像我可以用来重现我的错误的实际代码的最简单版本一样。我基本上使用钛中的 WebView 打开本地保存的 .htm 文件,以便我可以利用 HTML5 图形功能。我正在做的工作很好。问题是我需要将一些数据传递给 htm 文件,我正在按照文档的建议进行操作 - 使用 Ti.App.fireEvent - 这可以工作......一次。但是,如果我离开窗口然后再次导航回来,它会失败并给我一个 NS_ERROR_NOT_AVAILABLE。我已经在 Firefox 中尝试了此代码作为 Web 预览,并在 Android 设备和模拟器上尝试了此代码,每个都存在相同的问题。显然,如果视图被回调,它不会以相同的方式加载存在一些问题,我猜它是从堆栈中拉回的,这与“加载”事件侦听器或其他东西混淆,但我不知道如何修复它。这是我的代码的简化版本,只是为了演示这个问题:

app.js

Titanium.UI.setBackgroundColor('#000');

var win = Ti.UI.createWindow({
    layout: 'vertical',
});

var wv = Ti.UI.createWebView({
    url: 'test.htm',
    height: '50%'
});

var but = Ti.UI.createButton({
    width: 100,
    height: 50,
    title: 'Press',
});

var wvopen = false;

but.addEventListener('click', function() {
    if (wvopen === false) {
        win.add(wv);
        wvopen = true;
    } else {
        win.remove(wv);
        wvopen = false;
    }

});

wv.addEventListener('load', function() {
   Ti.App.fireEvent('go'); 
});

win.add(but);
win.open();

还有.htm文件:

test.htm

<!doctype html>
<html>
<head>
    <title>Test</title>
</head>
<body>
    <p>A Little Test</p>
    <script>
        var Ti = window.parent.Ti;
        Ti.App.addEventListener('go', function(){
            alert(1);
        });
    </script>
</body>
</html>

【问题讨论】:

    标签: android events webview titanium


    【解决方案1】:

    试试这个,

    but.addEventListener('click', function() {
       if (wvopen === false) {
          win.add(wv);
          wvopen = true;
       } else {
          win.remove(wv);
          wv.release();
          wvopen = false;
       }
    });
    

    【讨论】:

    • 我认为你的 html 文件名应该是 test.html 而不是 test.htm
    • 不好,由于某种原因,Firefox 告诉我 release() 不是一个函数。我知道..我查看了文档,它就在那里...重命名会产生 0 差异。
    【解决方案2】:

    我最终自己找到了答案。它在文档中,但要意识到问题到底是什么以及为什么会发生并不总是那么简单,所以我觉得值得我自己在这里回答以供其他人使用。

    关键点是这样的:

    “请记住,应用级事件是全局性的,这意味着它们在您的应用运行的整个过程中都保持在上下文中(除非您删除它们)。这也意味着它们引用的任何对象也将在您的应用程序运行时保持在范围内应用程序运行。这可能会阻止这些对象被垃圾收集。有关详细信息,请参阅管理内存和查找泄漏一章。"

    ~钛文档。

    链接:https://wiki.appcelerator.org/display/guides2/Event+Handling#EventHandling-Application-LevelEvents

    所以基本上事件监听器将存在,即使它没有加载并且你尝试删除它存在的上下文。因此,您必须同时删除事件侦听器并取消持有它的视图。

    实际上,根据您的具体情况,实现可能会有所不同,但这是我想出的。

    注意...可能有更有效的方法可以做到这一点,在这种情况下请告诉我。

    app.js
    
     /*
     * Build window and buttons
     */
    
    var win = Ti.UI.createWindow({
        layout: 'vertical',
        backgroundColor:'black'
    });
    
    
    var but = Ti.UI.createButton({
        top: 20,
        width: 200,
        height: 50,
        title: 'Toggle WV',
    });
    
    var but2 = Ti.UI.createButton({
        top: 20,
        width: 200,
        height: 50,
        title: 'Fire Event'
    });
    
    var wv;
    function newWv(){
        wv = Ti.UI.createWebView({
            top:20,
            right: 20,
            left: 20,
            height: '50%',
            url: 'test.htm',
        });
    }
    
    win.add(but);
    win.add(but2);
    
    /*
     * Main functionality goes here of tests goes here.
     */
    var isVisible = false;
    
    
    but.addEventListener('click', function() {
        if (isVisible) {
            win.remove(wv);
            Ti.App.fireEvent('close');
            wv = null;
            isVisible = false;
        } else {
            newWv();
            win.add(wv);
            isVisible = true;
        }    
    });
    
    but2.addEventListener('click', function() {
        try{
            Ti.App.fireEvent('go'); 
        } catch(e) {
            alert(e);
        }
    });
    
    win.open({modal:true});
    

    然后在 htm 文件中进行一些更改:

    test.htm
    
    <!doctype html>
    <html>
    <head>
        <title>Test</title>
    </head>
    <body>
        <p>A Little Test</p>
        <script>
            var Ti = window.parent.Ti;
            var go = function() {
                alert('called by Titanium app');
            };
            var close = function() {
                Ti.App.removeEventListener('go',go);
                Ti.App.removeEventListener('close',close);
            };
            window.addEventListener('load', function() {
                Ti.App.addEventListener('go', go);
                Ti.App.addEventListener('close', close);
            }); 
    
        </script>
    </body>
    </html> 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-07
      • 1970-01-01
      • 2013-10-11
      • 2018-09-13
      • 2022-12-07
      • 2020-07-04
      • 2018-05-08
      • 1970-01-01
      相关资源
      最近更新 更多