我已经与Phonegap支持人员以及比我更有经验的Android人员以及知识渊博的移动网络应用程序开发人员联系,以确定我的应用程序中出现奇怪错误的原因。据我所谈过的人说,问题可能源于任何这些地方(Android,PhoneGap插件或使用jQuery mobile)。
这是包含index.html的文件夹,其中包含我的Phonegap应用程序的代码: https://github.com/galenthomasramos/EcigSurvey/tree/master/platforms/android/assets/www
此应用程序的目标设备是Motorola Razr M.我使用本地通知插件提供一整天的通知。有时在点击通知时,我的onResume事件函数中的一些代码很晚才会被触发。我应该在恢复应用程序后立即收到并发出警报,但事后差不多会收到警报。当我尝试登录我的应用程序(登录屏幕是我的应用程序中出现的第一页)时,我发生了更大的问题(相同的症状 - 非常晚的函数调用),我已正确输入密码,但手机无法导航到下一页。页面无法重置而不能导航到下一页 - 我会收到不正确的用户输入警告并要求再次尝试,或者应用程序应该成功导航到下一页。
我应该提一下,这些错误似乎只有在通过通知访问应用程序时才会发生,如果我从正在运行的应用程序堆栈中恢复应用程序,则不会发生这种情况。
起初我认为可能在我的应用程序被暂停,或者Android可能会导致我的某些后台进程被终止时,变量在我的程序中被终止,可能会导致这种行为,但是在查看运行Android应用程序的应用程序,该应用程序可以观察内存使用量和任何垃圾收集量,看起来Android似乎没有发生任何事情。
我和别人谈过jQuery Mobile可能是罪魁祸首(显然jQuery Mobile的行为因设备平台而异,我似乎没有在我的Nexus 4上收到这些错误)也许我的页面事件没有正常工作?
我的onResume事件功能(应该在恢复时触发警报):
function onResumeApp(){
//Check to see if there is a suspension time set, if so, check to see if that time has passed, if so, resume normal app behavior
if(resumeTime != null){
//in the case of delaying a notification, need to change currentState to active through a timeout function...
// otherwise causes error in how missing a delayed a notification counts more than once
if(moment().isAfter(resumeTime)){
currentState = states.ACTIVE;
displayAppStatus(states.ACTIVE);
resumeTime = null;
}
}
if (hasMissedNotification){
alert("You have missed " + missedNotifications + " random prompt survey(s). Please remember to take as many surveys as possible.");
hasMissedNotification = false;
missedNotifications = 0;
}
...
}
在阅读暂停事件后可以导航到另一个页面吗?在这种情况下,我可以预见到在暂停事件监听器中读取任何代码时应用程序处于后台的问题...然后,为什么Phonegap会包含暂停事件功能,如果你不能写任何Javascript代码来使用它?
我的onPause事件功能:
function userHasGoneIdle(){
//If user goes idle and has started a random prompt survey but has not finished it before going idle,
//Need to record a survey as being abandoned
if(startedRandomPromptSurvey && !finishedRandomPromptSurvey){
//If a user delays a notification, don't want to add to missing notifications file yet.
if(currentState != states.DELAYED){
hasMissedNotification = true;
addToMissedNotifications(1, moment().toDate().toString());
startedRandomPromptSurvey = false;
finishedRandomPromptSurvey = false;
}
//If a user clicks a notification (indicates that they have started a random prompt interview), delays notification,
//then misses the delayed notificaiton, it will register both an abandoned as well as a missed, when really they have only missed
//the last delayed notification
}
writingToRandomPromptInt = false;
$("#login-password").val('');
if(!wakeUpFiring)
$.mobile.navigate('#login');
else
$.mobile.navigate('#wakeup');
resetSurveyWidgets();
console.log('userHasGoneIdle');
}
然后我有一堆代码由我使用的本地通知插件由事件监听器函数执行。这些事件可以在任何时候发生,如果应用程序位于前台或后台......当应用程序在后台时,它们当然不会可靠地发生,我需要改变它的工作方式,但我想知道是否有任何这些事件函数中的代码可能会导致问题(我想说是的,因为问题似乎只有在通过通知访问应用程序时才会发生)
本地通知事件功能:
ontrigger:
window.plugin.notification.local.ontrigger = function (id, state, json) {
console.log('\nontrigger() #' + id + " State: " + state + " @" + moment().toString());// + ' @' + JSON.parse(json).date);
//if(id != serviceNotificationID){
if(Math.abs(id >= notificationCount - 1 || notificationCount == 0)){
console.log('id - notificationCount == 0:' + id + ' - ' + notificationCount + ' = ' + (id - notificationCount));
clearPriorNotifications(function(){
addNewNotifications(function(){
formNotificationString(writeToNotificationFile);
});
});
}
triggerTime = moment().toDate().toString();
if(id == 0)
didMissDelayedNotification = true;
if(id != -99){
playNotificationAudio();
}
//In the case that the user does not access app when an alarm goes off by clicking notification,
//Have app navigate to wakeup screen
else{
playAlarmAudio();
didMissWakeUp = true;
wakeUpFiring = true;
$.mobile.navigate("#wakeup");
}
setTimeout(function(){
if(id != -1 && id != -99){
//if Havent clicked on a notificaiton, and the notificaiton snt a delayed notificaiton,
if(didMissNotificationArr[parseInt(id)] && id != 0){
console.log("@onTrigger: didMissNotificationArr[" + id + "] = " + didMissNotificationArr[id]);
hasMissedNotification = true;
addToMissedNotifications(2, triggerTime);
window.plugin.notification.local.cancel(id);
}
//for missed delayed notifications, only log missed if not clicked and only cancel if not clicked (and therefore cnaceled)
else if(id == 0 && didMissDelayedNotification){
console.log("@onTrigger: didMissDelayedNotification = " + didMissDelayedNotification);
hasMissedNotification = true;
addToMissedNotifications(2, triggerTime);
window.plugin.notification.local.cancel(id);
}
}
//Need to set boolean to remain at #wakeup, regardless of whether or not the user leaves the app during
//wakeup alarm
else if(id == -99 && didMissWakeUp){
wakeUpFiring = false;
window.plugin.notification.local.cancel(id);
}
else if(id == -1)
window.plugin.notification.local.cancel(id);
}, (180 * 1000));
//}
};
的onclick:
window.plugin.notification.local.onclick = function(id, state, json){
console.log('\n clicking notification #' + id);
//notificationTime = JSON.parse(json).date;
//if(id != serviceNotificationID){
//When clicking on a delayed notification
if(id == 0){
$.mobile.navigate('#delay');
didMissDelayedNotification = false;
startedRandomPromptSurvey = true;
finishedRandomPromptSurvey = false;
}
//When clicking on a test notification
else if(id == -1){
$.mobile.navigate("#login");
takingTestSurvey = true;
startedRandomPromptSurvey = false;
finishedRandomPromptSurvey = false;
}
//When clicking on a wakeup notification
else if(id == -99){
$.mobile.navigate("#wakeup");
startedRandomPromptSurvey = false;
finishedRandomPromptSurvey = false;
}
//When clicking on a standard, untouched notification
else{
$.mobile.navigate('#delay');
startedRandomPromptSurvey = true;
finishedRandomPromptSurvey = false;
didMissNotificationArr[parseInt(id)] = false;
}
oncancel:
window.plugin.notification.local.oncancel = function (id, state, json) {
console.log('\n CANCELLING notification #' + id + " State: " + state);
//console.log("caller is " + arguments.callee.caller.toString());
if(id != -99){
if(my_media){
my_media.stop();
//my_media.reset();
my_media.release();
}
}
//If wake up alarm notificaiton:
else{
wakeUpFiring = false;
//$.mobile.navigate("#login");
if(my_alarm_media){
my_alarm_media.stop();
//my_media.reset();
my_alarm_media.release();
}
}
};
为什么我的应用可能会在通知恢复后无响应?