이전 활동을 완료하고 새 활동을 시작하거나 그 반대의 경우도 마찬가지입니다.


80

두 코드 스 니펫에서 동일한 결과를 얻는다는 것을 알고 있습니다.

finish();
startActivity(newActivity);

startActivity(newActivity);
finish();

그들 사이에 큰 차이가 있다면 당신의 의견을 알고 싶습니다. 하나가 다른 것보다 낫습니까? 그렇다면 그 이유는 무엇입니까?

답변:


61

startActivity ()를 수행하면 이벤트 대기열에 인 텐트를 게시하는 것뿐입니다. 활동의 실제 시작은 가까운 장래에 비동기 적으로 발생합니다. 그래서 나는 둘 사이에 큰 차이를 보지 못합니다.


1
나에게도 현명하게 들립니다
Tima

6
저에게는 애니메이션이 다릅니다. 아래 내 대답을 참조하십시오.
Monstieur

하지만 접근 방식은 완전히 잘못되었습니다.이 유스 케이스에 실제로 존재하는 플래그 (매니페스트에서도 의도에 대한)가 있습니다.
Ewoks 2015-06-02

@Ewoks 제발 머리, 무슨 의미, 어떤 깃발?
Anthony

3
실제로 앱 작업 ​​동작에는 큰 차이가 있습니다. 나는 별도의 답변으로 문제를 자세히 설명했습니다.
Vit Khudenko 20.01.20

27

애니메이션은 분명히 다릅니다 (적어도 4.1 이상). finish()먼저 호출 하면 첫 번째 활동이 더 일찍 사라지기 시작하고 새 활동이 사라지기 전에 잠시 startActivity()검은 색 배경이 보일 수 있습니다. 먼저 호출 하면 이전 활동 위에 새 활동이 사라지고 검은 색 배경이 보이지 않습니다.


16

및 호출 순서에 따라 애플리케이션 태스크 동작에 중요한 차이가 있습니다.startActivity()finish()

내가 설명하고있는 사례는 현재 활동 (중지되는 활동)이 작업에서 유일한 활동 인 상황으로 만 범위가 지정됩니다.

일반적으로 시작 인 텐트 (다른 ​​활동을 시작하기 위해 만든 인 텐트)가 시스템에 의해 변경되지 않을 것으로 예상합니다. 를 호출하기 전에 작업 finish()마지막 활동에서를 호출 하면 그렇지 않습니다 startActivity().

이 경우 시스템 구성 요소 인 ActivityManager startActivity() 는 인 Intent.FLAG_ACTIVITY_NEW_TASK 텐트에 추가 플래그를 실행합니다 .

이 경우 LogCat에서 다음과 유사한 로그 항목을 확인할 수 있습니다.

W / ActivityManager : ActivityRecord {4a19b47 u0 com.foo.bar/com.foo.bar.SplashActivity t4928 f} 완료에서 startActivity가 호출되었습니다. Intent.FLAG_ACTIVITY_NEW_TASK for : Intent {cmp = com.foo.bar / com.foo.bar.MainActivity}

그리고 이것은 (일부 조건에서) 일이 잘못 될 수있는 전환점입니다.

요약하자면 FLAG_ACTIVITY_NEW_TASK, 의도에 추가되는 예기치 않은 부작용을 경험하지 않고 안전한 편이되고 싶다면 순서는 다음과 같아야합니다.

  • startActivity()
  • finish()

데모 프로젝트 .

화면 녹화 :


소스 코드를 살펴보면, Activity.startActivity ()는 궁극적으로 ActivityThread.sendActivityResult ()를 호출하고 이는 다시 scheduleSendResult ()를 호출하여 활동을 대기열에 추가합니다. 스레드는 나중에 처리합니다. 반면에 finish ()는 활동을 즉시 종료하는 ActivityManagerNative.finishActivity ()를 호출합니다.
Emmanuel

@Emmanuel, 귀하의 진술이 내가 설명한 문제와 관련이 있는지 파악하지 못했습니다. :)
Vit Khudenko 20.01.22

9

Emmanuels 답변 외에도 :

두 방법 startActivity과는 finish예약한다 모두 UI 스레드에 의해 처리되기 때문에, 호출 한 메소드의 마지막.


7

나는 두 번째 선택을 할 것입니다. 공식 소스에서 찾은 것에 대해서는 이것을 뒷받침하지 않습니다. 그러나 finish를 호출하기 전에 새로운 활동을 시작하는 것이 더 합리적입니다. 그러면 새로운 활동이 인 텐트를 통해 팝업됩니다. , 이제 백그라운드 활동은 모든 정리 메소드를 호출 할 수 있습니다.

반대로하면 청소가 완료되기 전에 의도를 실행할 시간이 없을 것입니다. 즉, 활동은 finish () 호출 후 startActivity ()를 호출합니까?

제가 말하려는 내용을 이해 하셨기를 바랍니다. 안전을 위해 두 번째 옵션을하겠습니다.


네, 당신의 생각을 이해했습니다. 논리적으로 들립니다. 그러나 나는이 상황이 가능할 수있을 때, 저를 상상 두지
TIMA

2

비슷한 문제가 있습니다.

Activity A: singleInstance
Activity B: singleInstance
Activity C: singleInstance

A starts B 
B starts C
C wants to start A:

내가 사용하는 경우 여기 :

finish();
startActivity(A);

유선이 발생합니다. 활동 B가 A 대신 포 그라운드로 나옵니다! 하지만 다음과 같이 코드를 변경하면 :

startActivity(A);
finish();

모든 것이 정상이고 활동 A가 표시됩니다.

나는 문제가 무엇인지 모르겠지만 첫 번째 경우에는 C가 startActivity 명령을 실행하기 전에 완료되어 백 스택 이 상황을 처리하고 최상위 활동 인 B를 보여줍니다! 그러나 두 번째 경우에는 모든 것이 정상적으로 발생합니다.


애플리케이션을 finish ()하면 안드로이드는 B 인 스택에서 LRU 활동을 가져옵니다. 또한 finish ()가 비동기가 아니라 즉각적인 것이라고 생각하게합니다.
Mehmet AVŞAR 2014

0

나는 보통 수행 startActivity()하기 전에 finish()내가 그 만들 것이라고 생각하는 이전 외출하기 전에 새로운 화면이 나온다.

내 앱에 로그인 페이지가 있습니다. 사용자 로그인이 성공하면 로그인 활동이 사라지고 주요 활동이 시작됩니다. Android 4에서 잘 작동합니다.

오늘은 머티리얼 디자인으로 다시 쓰고 싶었습니다. 하지만 큰 문제가 생겼습니다. 새로운 Android 스튜디오는 많은 리소스를 필요로하는 머티리얼 디자인으로 빈 활동을 만듭니다. 같은 과정이지만 오류가 발생했습니다.

11-26 18:20:44.450 18397-18397/? I/Choreographer: Skipped 42 frames!  The application may be doing too much work on its main thread.
11-26 18:20:44.485 18397-18408/? I/art: Background partial concurrent mark sweep GC freed 2864(191KB) AllocSpace objects, 4(43MB) LOS objects, 13% free, 100MB/116MB, paused 8.056ms total 39.767ms

mainActivity내 전화 logcat에서 시작할 때 내 앱이 많은 리소스를 사용한다고 말했습니다 . mainActivity기본 머티리얼 디자인 레이아웃이라는 점에 아무것도 없습니다 .

나는 순서를 바꾸었고 이제 내 전화에서 오류없이 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.