Android2012. 1. 30. 10:12
기획자가 원하는 대로 액티비티를 띄우고, 이동하고, 점프하는 방법에 대해 알아본다.


[관련글 링크] 
1. Activity Jump #1 "홈 액티비티로 이동하기"
2. Activity Jump #2 "액티비티 스택에 없었던 메인액티비티로 이동하기"


[목표]
아래와 같이 메인 액티비티에서 액티비티C까지 4개의 화면이 존재하는 앱을 구현하는데, 갑자기 기획자가 "어떤 페이지에서도 [HOME] 버튼을 누르면 메인 액티비티로 이동이 가능하도록 구현해주세요."라고 한다면.. 

"그냥 띄우면 되겠지~"한다면, 안드로이드 액비티비의 스택구조를 알아볼 필요가 있고, 
"뭔가 좀 꼬일 것 같은데~"한다면 액티비티를 띄울 때, 인텐트에 적용할 플래그(Intent.addFlags(...))에 대해 알아보면 된다.

위의 내용을 정리해서, 구현해본다.



[구현하기]
아래와 같이 4개의 액티비티를 준비한다.
[NEXT PAGE >] 버튼을 누르면 왼쪽에서 오른쪽 순서로 이동하도록 구현한다.
어느 페이지에서든 [Go to MAIN] 버튼을 누르면 무조건 맨 왼쪽의 메인액티비티로 이동한다.



아래는 "B 액티비티"의 구현한 예이다. (다른 페이지도 똑같이 구현한다.)
눈여겨 볼 부분은 Line 19~22 이다.
public class ActivityB extends Activity implements OnClickListener {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_b);
        
        Button btnGoToMain = (Button)findViewById(R.id.btnActB);
        btnGoToMain.setOnClickListener(this);
        Button btnNextPage = (Button)findViewById(R.id.btnActB_Next_Page);
        btnNextPage.setOnClickListener(this);
    }

	@Override
	public void onClick(View v) {
		int id = v.getId();
		
		switch (id) {
		case R.id.btnActB:
			Intent intentHome = new Intent(this, ActivityJumpDemoActivity.class);
			intentHome.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
			intentHome.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
			startActivity(intentHome);
			finish();
			break;
		case R.id.btnActB_Next_Page:
			Intent intent = new Intent(this, ActivityC.class);
			startActivity(intent);
		default:
			break;
		}
	}
}

Line 20 : "FLAG_ACTIVITY_CLEAR_TOP" 플래그. 간단히 현재 액티비티에서 어느 액티비티로 이동하는데, 스택 중간에 있었던 액티비티들을 지우는 역할은 한다고 이해하면 된다. 이 플래그가 없으면, 중간에 액티비티는 스택에 그대로 남아있기 때문에 이동 중간에  화면에 표출되어 UI 흐름을 망친다. 또한 시간이 지나면서 수 많은 액티비티가 쌓이게 되어 메모리 낭비를 초래한다.

FLAG_ACTIVITY_CLEAR_TOP 
If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.


Line 21 : "FLAG_ACTIVITY_SINGLE_TOP" 플래그. 띄우려는 액티비티가 스택 맨위에 이미 실행 중이라면 재사용하겠다는 의미로 해석하면 된다.

FLAG_ACTIVITY_SINGLE_TOP
If set, the activity will not be launched if it is already running at the top of the history stack. 


 즉, 이 플래그를 설정하지 않았을 때, 메인액티비티는 새롭게 생성된다.
onCreate(...)와 onResume(...) 함수에 로그를 찍어 테스트 한 결과는 아래와 같다.


"A액티비티->메인" 으로 이동할때, 

1. FLAG_ACTIVITY_SINGLE_TOP 플래그 ON



2. FLAG_ACTIVITY_SINGLE_TOP 플래그 OFF 


결국,  FLAG_ACTIVITY_SINGLE_TOP를 설정하면, 기존에 띄워져있던 액티비티를 재사용하기 때문에 onCreate(...)가 불리지 않는다.


[액티비티 스택으로 확인하기]
(스택을 확인하는 방법은 이전 글을 참고하세요.)

public void onClick(View v) {
	int id = v.getId();
	
	switch (id) {
	case R.id.btnActC:
		Intent intentHome = new Intent(this, ActivityJumpDemoActivity.class);
		intentHome.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
		intentHome.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
		startActivity(intentHome);
		finish();
		break;
	default:
		break;
	}
}


"매인액티비티 -> ... -> 액티비티 C"까지 흘러온 상태에서 [Go to MAIN] 버튼을 눌렀을 때의 스택을 확인해봤다.
위에 코드의 Line 7,8을 ON했을 때와 OFF했을 때를 비교한 결과는 아래와 같다.



MAIN->A->B->C까지 정상적으로 이동했을 때

  Running activities (most recent first):

    TaskRecord{3026a910 #82 A com.juno.activityjump.demo}

      Run #4: HistoryRecord{30186310 com.juno.activityjump.demo/.ActivityC}

      Run #3: HistoryRecord{3021e1e0 com.juno.activityjump.demo/.ActivityB}

      Run #2: HistoryRecord{303b3e08 com.juno.activityjump.demo/.ActivityA}

      Run #1: HistoryRecord{300251c8 com.juno.activityjump.demo/.ActivityJumpDemoActivity}

    TaskRecord{30064818 #2 A com.lge.launcher}

      Run #0: HistoryRecord{2fcff6e0 com.lge.launcher/.Launcher}



C 에서 -> HOME으로 이동했을 때 (2개의 플래그 ON)

  Running activities (most recent first):

    TaskRecord{3026a910 #82 A com.juno.activityjump.demo}

      Run #1: HistoryRecord{300251c8 com.juno.activityjump.demo/.ActivityJumpDemoActivity}

    TaskRecord{30064818 #2 A com.lge.launcher}

      Run #0: HistoryRecord{2fcff6e0 com.lge.launcher/.Launcher}



C 에서 -> HOME으로 이동했을 때 (2개의 플래그 OFF)

  Running activities (most recent first):

    TaskRecord{301996d8 #83 A com.juno.activityjump.demo}

      Run #4: HistoryRecord{3035d6c0 com.juno.activityjump.demo/.ActivityJumpDemoActivity}

      Run #3: HistoryRecord{302c4f30 com.juno.activityjump.demo/.ActivityB}

      Run #2: HistoryRecord{3012aa08 com.juno.activityjump.demo/.ActivityA}

      Run #1: HistoryRecord{2ffb9170 com.juno.activityjump.demo/.ActivityJumpDemoActivity}

    TaskRecord{30064818 #2 A com.lge.launcher}

      Run #0: HistoryRecord{2fcff6e0 com.lge.launcher/.Launcher}




[참고자료]
    http://developer.android.com/reference/android/content/Intent.html


[다운로드]
    전체소스





Posted by 데브로망스