BroadcastReceive에서 앱의 currentactivity를 부를 때 앱이 재시작되는 문제

https://github.com/timanrebel/Parse 를 이용해서 안드로이드의 Push를 쓰고 있습니다.
이 모듈도 GCM과 같이 BroadcastReceiver를 이용해서 Push Noticifation을 알림바에서 눌렀을때 반응을 처리하는데요.

@Override
public void onPushOpen(Context context, Intent intent) {
    Log.d("onPushOpen", "Clicked");

    if(ParseModule.getInstance() != null) {
        Log.d("onPushOpen", "App is running");
        Intent i = new Intent(context, TiApplication.getAppRootOrCurrentActivity().getClass());
        i.putExtras(intent.getExtras());
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(i);
    }
    ...
}

이렇게 말이죠. 그런데 처음 앱을 구동 시켰을 때는 정상적으로 열려 있는 앱을 찾아서 보여주기만 하는 행동을 합니다.
(CurrentActivity가 잘 동작해서 Paused인 것을 Resumed 시켜주는 것이죠.)

그런데, 안드로이드의 멀티태스킹 버튼이나 홈버튼을 길게 눌러서 나오는 최근task보기(작업관리자)에서 앱을 종료시켜 버리고 (Activity가 사라진거죠.)
앱을 다시 켜고 나면 그 뒤로는 Push를 눌러서 저 동작이 수행될 때 앱이 계속 재시작됩니다.
멀쩡히 CurrentActivity가 있는데 Resumed되지 않고 RootActivity(스플래쉬스크린)을 실행 시키는거죠.

ti sdk는 3.5.1.GA를 쓰고 있구요. 이건 타이타늄의 버그라고 생각이 됩니다.
이 현상(Push를 누르면 앱이 재실행되는것)은 tishadow로 build후 bundle를 한번 deploy하고 나면 똑같이 발생해요.

그래서 안드로이드 Parse Push 모듈을 fork해서 건드려봤습니다.
TiApplication.getAppRootOrCurrentActivity() 를 TiApplication.getAppCurrentActivity() 로 바꾸면 검은 창만 열립니다.

결론은 앱이 Restart되면, CurrentActivity를 제대로 관리하지 못하는것 같습니다.
그래서 TiApplication.getAppRootOrCurrentActivity()에서 계속 RootActivity를 반환해서 앱이 재시작 되는 것이죠.

한 12시간에 걸쳐서 온갖 삽질을 다 해봤는데, 이게 해결이 안되더라구요… 그래서 고심 끝에 이렇게 처리했습니다.

@Override
public void onPushOpen(Context context, Intent intent) {
    Log.d("onPushOpen", "Clicked");

    if(ParseModule.getInstance() != null) {
        Log.d("onPushOpen", "App is running");
        bringFront(context);
    }
    ...
}



private static boolean bringFront(Context context) {
		boolean flag = true;
		String packageName = context.getApplicationContext().getPackageName();
		try {
			final ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
		    final List<RecentTaskInfo> recentTasks = activityManager.getRecentTasks(Integer.MAX_VALUE, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
		    
		    RecentTaskInfo recentTaskInfo = null;
		     
		    for (int i = 0; i < recentTasks.size(); i++) 
		    {
		        if (recentTasks.get(i).baseIntent.getComponent().getPackageName().equals(packageName)) {
		           recentTaskInfo = recentTasks.get(i);
		           break;
		        }
		    }
		     
		    if(recentTaskInfo != null && recentTaskInfo.id > -1) {
		        activityManager.moveTaskToFront(recentTaskInfo.persistentId, ActivityManager.MOVE_TASK_WITH_HOME);
		        return flag;
		    }
			
		} catch (Exception exception) {
			flag = false;
			exception.printStackTrace();
		}
		return flag;
}

activityManager를 이용해서 titanium app의 task를 식별해서 moveTaskToFront 하기로 말이죠;;;;;;

으하하하하하…ㅠ

이렇게 하면 앱의 재시작 없이 정상적으로 앱이 Resume됩니다…

권한 2개가 더 필요해서 timodule.xml에는 아래 2줄이 추가되어야 하구요.

    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.REORDER_TASKS" />

이걸 Pull request를 날려야 하는건지 아닌건지 잘 모르겠네요…

암튼 이걸로 한참 삽질했더니 아이고 힘드네요. 이거 ㅠ_ㅠ

1개의 좋아요

주말인데 일하시는거에요?

다음 주말에 휴가여서요.
요 몇일 게시물 올린것 처럼 매일 삽질을 하고 있어서…
이번 주말은 하루는 일했어요.

뭘하든 처음엔 항상 삽질이죠. 저도 요즘 이래저래 삽질하고 있어요. ^^
화이팅입니다!!!

1개의 좋아요