2015-04-12 184 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差異。 –