이력서가 아닌 앱이 다시 시작됨
누군가가 해결책이 아니라면 적어도 행동에 대한 설명을 알아낼 수 있기를 바랍니다.
문제 :
일부 장치에서는 실행기 아이콘을 누르면 현재 작업이 다시 시작되고 다른 장치에서는 초기 실행 의도가 발생합니다 (효과적으로 앱을 다시 시작). 왜 이런 일이 발생합니까?
세부 사항 :
"런처 아이콘"을 누르면 앱이 정상적으로 시작됩니다. 즉, 첫 번째 이름
Activity
과 동작
android.intent.action.MAIN
및 카테고리로 인 텐트가 시작된다고 가정 합니다
android.intent.category.LAUNCHER
. 그러나 항상 그런 것은 아닙니다.앱 후 실행 아이콘이 이미 실행중인 누르면 기기의 대부분에서, 그 과정에서 현재 실행중인 활동 (재개
NOT
초기
Activity
). OS 메뉴의 "최근 작업"에서 선택한 것과 같은 방식으로 재개됩니다. 이것은
모든
장치에서 원하는 동작 입니다.그러나 선택한 다른 장치에서는 다른 동작이 발생합니다.
- Motorola Xoom에서 실행기 아이콘을 누르면 현재 실행중인 항목에 관계없이 앱이
항상
초기 시작을 시작합니다
. 런처 아이콘은 항상 "LAUNCHER"의도를 시작한다고 가정합니다.Activity
- Samsung Tab 2에서 런처 아이콘을 누르면 앱을 방금 설치 한 경우 항상 초기
(Xoom과 동일)가 시작되지만 설치 후 장치를 다시 시작하면 런처 아이콘이 대신 표시됩니다 앱을 다시 시작하십시오. 이 장치가 "설치된 앱"을 장치 시작시 조회 테이블에 추가하여 실행기 아이콘이 작업 실행을 올바르게 재개 할 수 있다고 가정합니까?Activity
내 문제와 비슷한
소리로
많은 답변을 읽었 지만 단순히 추가
android:alwaysRetainTaskState="true"
하거나 사용
launchMode="singleTop"
하는
Activity
것이 답이 아닙니다.
편집하다:
이 앱을 가장 최근에 출시 한 후 처음 다시 시작한 후
모든
기기 에서이 동작이 발생하기 시작했습니다 . 나에게 미친 것처럼 보이지만 다시 시작 프로세스를 살펴보면 실제로 무엇이 잘못되었는지 찾을 수 없습니다.
발생한 동작은 API 1 이후 일부 Android 런처에서 발생하는 문제로 인해 발생합니다.
https://code.google.com/p/android/issues/
에서 버그 및 가능한 솔루션에 대한 세부 사항을 찾을 수 있습니다. detail? id = 2373 입니다.사용자 정의 실행기 / 스킨을 사용하는 다른 제조업체뿐만 아니라 삼성 기기에서도 비교적 일반적인 문제입니다. 주식 Android 런처에서 문제가 발생하는 것을 보지 못했습니다.기본적으로 앱이 실제로 완전히 다시 시작되지는 않지만 실행기에서 앱을 다시 시작하면 시작 활동이 시작되어 활동 스택 맨 위에 추가됩니다. 앱을 다시 시작하고 시작 활동이 표시 될 때 뒤로 단추를 클릭하여이 경우를 확인할 수 있습니다. 그런 다음 앱을 다시 시작할 때 표시 될 것으로 예상되는 활동으로 이동해야합니다.이 문제를 해결하기 위해 구현하기로 선택한 해결 방법은 초기 활동을 시작하려는 의도에서 Intent.CATEGORY_LAUNCHER 범주 및 Intent.ACTION_MAIN 작업을 확인하는 것입니다. 이 두 플래그가 있고 활동이 작업의 루트에 있지 않은 경우 (앱이 이미 실행 중임을 의미) 초기 활동에서 finish ()를 호출합니다. 그 정확한 해결책은 당신에게 효과가 없을 수도 있지만 비슷한 것이 있어야합니다.초기 / 시작 활동의 onCreate ()에서 수행하는 작업은 다음과 같습니다.
if (!isTaskRoot()
&& getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)
&& getIntent().getAction() != null
&& getIntent().getAction().equals(Intent.ACTION_MAIN)) {
finish();
return;
}
이 질문은 2016 년에도 여전히 관련이 있습니다. 오늘 QA 테스터는 Android M
의 주식 런처
에서 다시 시작하지 않고 내 앱이 다시 시작되는 것으로보고했습니다 .실제로 시스템은 시작된 활동을 현재
에 추가했지만 다시 시작이 발생하여 작업을 잃은 것처럼
사용자에게 표시
되었습니다. 순서는 다음과 같습니다.
- Play 스토어 (또는 사이드로드 APK)에서 다운로드
- Play 스토어 대화 상자에서 앱 실행 : 활동 A가 나타납니다. [작업 스택 : A]
- 활동 B로 이동 [작업 스택 : A-> B]
- '홈'버튼을 누르십시오
- 앱 드로어에서 앱 시작 : 활동 A가 나타납니다! [작업 스택 : A-> B-> A] (사용자는 '뒤로'버튼을 눌러 여기에서 활동 'B'로 이동)
참고 :이 문제는 ADB를 통해 배포 된 디버그 APK의 경우 Play 스토어에서 다운로드하거나 사이드로드 된 APK에서만 나타납니다. 후자의 경우 5 단계의 실행 의도
Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT
에는 디버그 경우가 아닌 플래그가 포함되어 있습니다. 앱이 실행기에서 콜드 스타트되면 문제가 사라집니다. 내 의심은 작업이 완전히 지워질 때까지 올바른 시작 동작을 방해하는 잘못된 (더 정확하게, 비표준) 의도로 작업이 시드되었다는 것입니다.다양한
시도 했지만 이러한 설정은 사용자가 기대하는 표준 동작과 너무 다릅니다. 활동 B에서 작업을 다시 시작하십시오 . 페이지 하단의
에서 예상되는 동작에 대한 다음 정의를 참조하십시오. '작업 시작'에서 :
이러한 종류의 인 텐트 필터를 사용하면 활동에 대한 아이콘 및 레이블이 애플리케이션 실행기에 표시되어 사용자에게 활동을 시작하고 실행 후 언제라도 작성된 태스크로 돌아갈 수있는 방법을 제공합니다.
이 관련성 이 있음을 발견 하고 사용자가 응용 프로그램을 열 때 적절하게 재개되도록 루트 활동 (A)의 'onCreate'메서드에 다음을 삽입했습니다.
/**
* Ensure the application resumes whatever task the user was performing the last time
* they opened the app from the launcher. It would be preferable to configure this
* behavior in AndroidMananifest.xml activity settings, but those settings cause drastic
* undesirable changes to the way the app opens: singleTask closes ALL other activities
* in the task every time and alwaysRetainTaskState doesn't cover this case, incredibly.
*
* The problem happens when the user first installs and opens the app from
* the play store or sideloaded apk (not via ADB). On this first run, if the user opens
* activity B from activity A, presses 'home' and then navigates back to the app via the
* launcher, they'd expect to see activity B. Instead they're shown activity A.
*
* The best solution is to close this activity if it isn't the task root.
*
*/
if (!isTaskRoot()) {
finish();
return;
}
UPDATE: moved this solution away from parsing intent flags to querying if the activity is at the root of the task directly. Intent flags are difficult to predict and test with all the different ways there are to open a MAIN activity (Launch from home, launch from 'up' button, launch from Play Store, etc.)
Aha! (tldr; See the statements in bold at the bottom)
I've found the problem... I think.
So, I'll start off with a supposition. When you press the launcher, it either starts the default Activity
or, if a Task
started by a previous launch is open, it brings it to the front. Put another way - If at any stage in your navigation you create a new Task
and finish
the old one, the launcher will now no longer resume your app.
If that supposition is true, I'm pretty sure that should be a bug, given that each Task
is in the same process and is just as valid a resume candidate as the first one created?
My problem then, was fixed by removing these flags from a couple of Intents
:
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK );
While it's quite obvious the FLAG_ACTIVITY_NEW_TASK
creates a new Task
, I didn't appreciate that the above supposition was in effect. I did consider this a culprit and removed it to test and I was still having a problem so I dismissed it. However, I still had the below conditions:
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
My splash screen was starting the "main" Activity
in my app using the above flag. Afterall, If I had "restart" my app and the Activity
was still running, I would much rather preserve it's state information.
You'll notice in the documentation it makes no mention of starting a new Task
:
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.
For example, consider a task consisting of the activities: A, B, C, D. If D calls startActivity() with an Intent that resolves to the component of activity B, then C and D will be finished and B receive the given Intent, resulting in the stack now being: A, B.
The currently running instance of activity B in the above example will either receive the new intent you are starting here in its onNewIntent() method, or be itself finished and restarted with the new intent. If it has declared its launch mode to be "multiple" (the default) and you have not set FLAG_ACTIVITY_SINGLE_TOP in the same intent, then it will be finished and re-created; for all other launch modes or if FLAG_ACTIVITY_SINGLE_TOP is set then this Intent will be delivered to the current instance's onNewIntent().
This launch mode can also be used to good effect in conjunction with FLAG_ACTIVITY_NEW_TASK: if used to start the root activity of a task, it will bring any currently running instance of that task to the foreground, and then clear it to its root state. This is especially useful, for example, when launching an activity from the notification manager.
So, I had the situation as described below:
A
launchedB
withFLAG_ACTIVITY_CLEAR_TOP
,A
finishes.B
wishes to restart a service so sends the user toA
which has the service restart logic and UI (No flags).A
launchesB
with FLAG_ACTIVITY_CLEAR_TOP,A
finishes.
At this stage the second FLAG_ACTIVITY_CLEAR_TOP
flag is restarting B
which is in the task stack. I'm assuming this must destroy the Task
and start a new one, causing my problem, which is a very difficult situation to spot if you ask me!
So, if all of my supposition are correct:
- The
Launcher
only resumes the initially created Task FLAG_ACTIVITY_CLEAR_TOP
will, if it restarts the only remainingActivity
, also recreate a newTask
I had the same issue on Samsung devices. After searching a lot, none of these answers worked for me. I found that in the AndroidManifest.xml file, launchMode
is set to singleInstance
(android:launchMode="singleInstance"
). Removing the launchMode
attribute fixed my issue.
This solution worked for me:
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
return false;
}
else
return super.onKeyUp(keyCode, event);
}
credit: I need to minimize the android application on back button click
may not work on all devices, but successfully creates home button behavior when back button is pressed, thus stopping the activity rather than finishing it.
On my Cat s60, I had enabled "Don't keep activities" in Developer options, disabling this again allowed me to switch apps without loosing state of the apps...
Solution for the people who have no idea about programming and experiencing this issue in their android phone. This happens mostly due to upgrade of android version(only my assumption). After upgrade all your apps gets optimized to use less battery. But, this in turn slows down your device.
How to solve
Go to settings>>Apps>>apps settings(look for settings sign anywhere on the screen- it is different on different devices)>>battery optimization(or similar opti[enter image description here][1]on)>> move all apps to 'not optimised' state (have to do 1 by 1 manually -may be allow/disallow in some phones). Your launcher app need to be 'not optimised'(Zen UI launcher in my case - this is the culprit I guess- you could try optimising/Not optimizing and restarting different app if you have time). Now restart your phone. (no need to reset data/safe mode or any trouble)
Try multitasking now. :) Pressing the launcher icon should now results in the current task being resumed. :) Your device will become Don't worry about battery, it will drain anyway.
I had the same problem, the cause was:
(Kotlin code, in MainActivity)
override fun onBackPressed() {
finish()
}
So when navigating to my MainActivity from my LoginActivity I use this:
val intent = Intent(this, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
When using these flags I dont have to have a onBackPressed() in my MainActivity, it will exit the app naturally on back click. And when pressing the Home button and going back into the app it dosen't restart.
Priceless to your users. The perfect resume even after sitting weeks in the recently used app list.
It looks like a resume to the user but actually is a full blown start.
Background: The memory used by apps that are in the main activity that haven't started a task is easy to reclaim. The os can simply restart the app with the original bundle passed to onCreate. You can however add to the original bundle in onSaveInstanceState
so when your app is restarted by the OS you can restore the instance state and no one is the wiser on whether the app restarted or resumed. Take for example the classic map program. The user moves to a position on the map and then presses the home key. Two weeks later this mapping app is still in the list of recent apps along with facebook, pandora, and candy crush. The OS doesn't just save the name of the app for the recently used apps it also saves the original bundle used to start the app. However the programmer has coded the onSaveInstanceState
method so the orignal bundle now contains all the materials and information necessary to construct the app so it looks like it was resumed.
Example: Save the current camera position in onSaveInstanceState just incase the app is unloaded and has to be restarted weeks later from the list of recent apps.
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
// save the current camera position;
if (mMap != null) {
savedInstanceState.putParcelable(CAMERA_POSITION,
mMap.getCameraPosition());
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// get the exact camera position if the app was unloaded.
if (savedInstanceState != null) {
// get the current camera position;
currentCameraPosition = savedInstanceState
.getParcelable(CAMERA_POSITION);
}
Note: you can also use the onRestoreInstanceState
method but I find it easier to restore the instance in onCreate
.
This is more than likely what is happening in your app. On some devices your app is unloaded to free memory. Yes there are some flags that help but the flags will not pick up every nuance of your app and the flags won't keep you alive for weeks like onSaveInstanceState
will. You have to code the perfect two weeks later resume. It will not be an easy task for the complex app but we are behind you and are here to help.
Good Luck
참고URL : https://stackoverflow.com/questions/19545889/app-restarts-rather-than-resumes
'programing' 카테고리의 다른 글
yum 패키지가 설치된 경로 결정하기 (0) | 2020.05.24 |
---|---|
Python 하위 프로세스 통신 방법을 사용할 때 종료 코드를 얻는 방법은 무엇입니까? (0) | 2020.05.24 |
메이븐 스킵 테스트 (0) | 2020.05.23 |
O (nlogn) Algorithm-이진 문자열 내에서 균등 한 간격으로 3 개 찾기 (0) | 2020.05.23 |
여러 열에 대한 DISTINCT 계산 (0) | 2020.05.23 |