2015-04-12 2 views
0

Пожалуйста, извините уродливый код, это здесь, как самая простая версия моего реального кода, которую я могу использовать для воспроизведения моей ошибки. Я в основном использую WebView в титане, чтобы открыть локально хранящийся файл .htm, чтобы я мог использовать возможности HTML5 для графики. То, что я делаю, отлично работает. Проблема в том, что мне нужно передать некоторые данные в файл htm, который я делаю точно так, как рекомендуют документы, - используя Ti.App.fireEvent - и это работает ... один раз. Но если я уйду от окна, а затем вернусь назад, это не сработает и даст мне NS_ERROR_NOT_AVAILABLE. Я пробовал этот код в firefox как веб-предварительный просмотр, а также на 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

Так в основном слушатель событий будет существовать, даже если он не загружен, и вы пытаетесь удалить контекст, в котором она существует. Поэтому вы должны удалить и прослушиватель событий, и аннулировать представление, которое его удерживает.

На практике реализация может немного изменяться в зависимости от вашей специфики, но это то, к чему я пришел.

NB ... там могут быть более эффективные способы сделать это, и в этом случае, пожалуйста, дайте мне знать.

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

Ничего хорошего, по какой-то причине светлячок говорит мне что release() не является функцией. Я знаю .. Я посмотрел в документах, и он там ... переименование составляет 0 разностей. –

Смежные вопросы