안드로이드에서 Home 버튼을 눌렀다가 다시 앱으로 돌아오면 전역변수가 모두 초기화됩니다.

안녕하세요?

현재 개발 중인 앱을 빌드하여 IOS에서 실행하면 잘 되는데,
안드로이드에서 Home 버튼을 눌렀다가 다시 앱으로 돌아오면 전역변수가 모두 초기화됩니다.
다른 앱을 실행하지 않고 바로 되돌아와도 이런 현상이 발생하는데 원인을 모르겠네요.

IOS와 달리 안드로이드에서는 Home 버튼을 누를 때 pause나 paused 이벤트가 발생하지 않고 Home 버튼 이벤트 캐치도 불가능하여 bencoding 모듈을 사용하여 foreground / background 전환을 감지하여 처리하고,
안드로이드 back 버튼을 누를 때는 아래 코드로 Home 버튼이 눌러지도록 하여 동일한 루틴으로 pause / resume 과정을 처리하고 있습니다.

function pressAndroidHomeButton() {
    var intent = Ti.Android.createIntent({
        action: Ti.Android.ACTION_MAIN
    });
    intent.addCategory(Ti.Android.CATEGORY_HOME);
    Ti.Android.currentActivity.startActivity(intent);
}

또 윈도우를 생성할 때 exitOnClose 플래그를 설정해도 동작하지 않는 경우가 많아서
아래 함수를 대신 사용하고 있습니다.

function setExitOnClose(win) {
    win.addEventListener(‘android:back’, pressAndroidHomeButton);
}

전역변수가 초기화되는 원인이 이 코드들에 있나 싶어서 모두 주석처리하고 실행해도 여전히 발생합니다.
의심되는 부분이 있으시면 좀 말씀해주시면 감사하겠습니다.

그리고 안드로이드에서 Home / Back 버튼을 처리하는데 표준화된 방법이 있나요?
다른 분들은 안드로이드에서 Home / Back 버튼 처리를 어떻게 하시는지 궁금합니다.

전역변수라고 하심은 어디서 선언한 변수이신가요?
Alloy.Globals가 초기화 되나요?
아니면, 겪으시는 문제가 앱이 재실행되시는건가요?

저는 안드로이드 back버튼에 대한 처리는 아래와 같이 합니다.

  1. 우선, window.open으로 띄운 윈도우는 back버튼을 누르면 window.close가 일어나니 따로 처리하지 않구요.
  2. 메인 윈도우=액티비티=index는 back버튼 이벤트를 받아서 view의 history대로 거슬러가 주도록 하고 있습니다.
  3. 최종적으로 history가 없으면 메인 윈도우=액티비티를 닫아주고 이 메인 윈도는 exitOnClose 속성을 가지고 있어서 앱이 종료됩니다.

home버튼에 대한 처리는 따로 하지 않습니다.
메인 윈도우가 살아 있으니 resume될 때 그 전 상태 그대로 동작합니다.

안드로이드는 액티비티 별로 각각 resume/pause 이벤트를 받을 수 있습니다.
주의 하실 점은 window.open으로 새 액티비티가 열리면, 메인 윈도우는 paused됩니다. (open된 액티비티가 close되면 resume되구요.)
방법은 아래 링크를 참고해주세요.

1개의 좋아요

제가 전역변수라고 말씀드린 변수들은 app.js에 선언되어 다른 함수나 모듈들에서 그대로 사용할 수 있는 변수들입니다.

제가 C/C++ 개발을 해 온 터라 Alloy 프로젝트는 사용하지 않고 Classic 프로젝트로 시작을 한 상태라서 Alloy는 사용할 수 없습니다.

제가 구현하고자 한 기능은 Home / Back 버튼이 눌러지면 앱은 그대로 살아있지만 서버와의 소켓 접속은 끊어지도록 만들려고 합니다.

조언해주신 구현 방법과 차이점으로 보이는 부분은 제가 개발 중인 앱은 Home 버튼을 눌렀을 때 아무 처리를 하지 않으면 소켓이 계속 연결된 상태로 남아 있다는 것입니다.
그래서 Home과 Back 버튼을 동일한 pause 루틴을 실행하여 접속을 종료하도록 만들려고 하고 있습니다.

제 설명이 충분하지 않을 것으로 보입니다.
궁금하신 부분은 또 말씀해주세요. ^^

context.js는 JS코드에서는 이 스타일로 부르시면, home에 paused 이벤트를 받으실 수 있습니다.

require('Context').on('xxxx', this.activity);

전 메인윈도우의 open 이벤트에 아래와 같이 할당해서 사용합니다.

APP.MainWindow.addEventListener("open", function(){
    require('Context').on('index', this.activity);
    APP.MainWindow.removeEventListener('open', arguments.callee);
});

Ti.App.addEventListener("paused", APP.exitObserver);
Ti.App.addEventListener("close", APP.exitObserver);
Ti.App.addEventListener("resumed", APP.resumeObserver);

그리고 alloy mvc를 안쓰신다고 하더라도 alloy project가 코딩하시기 더 유리합니다.
classic 코드를 alloy의 controller부분에 코딩하는 것으로 view/tss 없이 개발이 가능합니다.
전환은 어렵지 않으니 한번 고려해보세요 :smile:

1개의 좋아요

저도 검색해보면서 Context 모듈을 js에서는 어떻게 쓸 수 있을지 궁금했었는데, 정확하게 짚어주셨네요 ^^
알려주신 방법대로 사용해 보겠습니다.

그리고 Alloy 프로젝트로 전환은 테스트를 좀 해보고 전환하는 방향으로 해봐야겠네요.

감사합니다.

그리고 back 버튼을 눌렀을때 main activity가 종료되는걸 막고 싶으시면,

var intent = Ti.Android.createIntent({
    action: Ti.Android.ACTION_MAIN
});
intent.addCategory(Ti.Android.CATEGORY_HOME);
Ti.Android.currentActivity.startActivity(intent);

위에 적으신 코드를 back 버튼 이벤트에 추가하시는게 맞습니다.

1개의 좋아요

아, 저 코드를 back 버튼에 할당해야 되는거였군요,
그렇게 해보도록 하겠습니다. ^^


아, 소스코드를 확인해 보니 현재 전 소스코드 내에서 tabGroup 1개와
tabGroup에 속하지 않은 window 1개의 android:back 이벤트에만 세팅하도록 되어 있네요.

그리고 androidback 이벤트 핸들러는 return false; 로 끝나야 close되는걸 막으실 수 있을거에요.

1개의 좋아요

제 경우에는 android:back 이벤트 핸들러에 return false를 추가해도 달라지는 점이 없네요.

안드로이드 Back / Home 이벤트를 처리하는 구조부터 바꿔봐야 될 것 같습니다. ^^