2015-04-12 135 views
0

请原谅丑陋的代码,这里只是我可以用来重现我的错误的实际代码的最简单的版本。我基本上使用钛的WebView来打开本地保存的.htm文件,以便我可以利用HTML5图形功能。我正在做的很好。问题是我需要将一些数据传递给htm文件,我正在按照文档推荐的方式执行 - 使用Ti.App.fireEvent - 并且这个工作...一次。但是,如果我离开窗口并再次导航回它失败,并给我一个NS_ERROR_NOT_AVAILABLE。我已经尝试在Firefox中的这个代码作为Web预览,并在Android设备和模拟器中使用相同的问题。很明显,它有一些问题,如果视图被回调,它不会以相同的方式加载,我猜测它被从堆栈上拉回来,这与'load'事件监听器或某事有关,但我不知道如何修复它。这里是我的代码的简化版本,只是为了演示问题:问题与webview和Ti.App.addEventListener导致崩溃

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> 

回答

0

,我发现自己的答案最终。这是在文档中,但意识到问题实际是什么,为什么它发生并不总是很简单,所以我觉得值得我在这里回答自己,供他人使用。

的关键点是这样的:

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

〜钛文件。

链接: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> 
0

试试这个,

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

我想你的HTML文件名应该是没有的test.html TEST.HTM –

+0

没有良好的,由于某种原因,Firefox是告诉我该release()不是一个函数。我知道..我看了文档,它在那里...重命名使0差异。 –