더 이상 백그라운드에서 실행되지 않도록 애플리케이션을 닫고 싶습니다.
그렇게하는 방법? Android 플랫폼에서 이것이 좋은 방법입니까?
"뒤로"버튼을 사용하면 앱이 닫히지 만 백그라운드에 남아 있습니다. 백그라운드에서 이러한 앱을 종료하기위한 "TaskKiller"라는 응용 프로그램도 있습니다.
더 이상 백그라운드에서 실행되지 않도록 애플리케이션을 닫고 싶습니다.
그렇게하는 방법? Android 플랫폼에서 이것이 좋은 방법입니까?
"뒤로"버튼을 사용하면 앱이 닫히지 만 백그라운드에 남아 있습니다. 백그라운드에서 이러한 앱을 종료하기위한 "TaskKiller"라는 응용 프로그램도 있습니다.
답변:
Android에는 문서에 따라 애플리케이션을 안전하게 닫을 수있는 메커니즘이 있습니다. 종료 된 마지막 활동 (일반적으로 애플리케이션이 시작될 때 처음 나타난 기본 활동)에서 onDestroy () 메서드에 몇 줄만 배치합니다. System.runFinalizersOnExit (true)를 호출 하면 응용 프로그램이 종료 될 때 모든 개체가 종료되고 가비지 수집됩니다. 원하는 경우 android.os.Process.killProcess (android.os.Process.myPid ()) 를 통해 애플리케이션을 빠르게 종료 할 수도 있습니다 . 이를 수행하는 가장 좋은 방법은 다음과 같은 메서드를 도우미 클래스에 넣은 다음 앱을 종료해야 할 때마다 호출하는 것입니다. 예를 들어 루트 활동의 destroy 메소드에서 (앱이이 활동을 절대로 죽이지 않는다고 가정) :
또한 Android는 애플리케이션에 HOME 키 이벤트를 알리지 않으므로 HOME 키를 눌러도 애플리케이션을 닫을 수 없습니다 . Android 는 개발자가 사용자가 애플리케이션을 떠나는 것을 막을 수 없도록 홈 키 이벤트를 자체적으로 예약합니다 . 그러나 HOME 키를 눌렀다 고 가정하는 도우미 클래스에서 플래그를 true로 설정 한 다음 HOME 키가 눌리지 않았 음을 나타내는 이벤트가 발생하면 플래그를 false로 변경하여 HOME 키가 눌려진 것을 확인할 수 있습니다. 활동 의 onStop () 메서드 에서 누른 HOME 키를 확인합니다 .
모든 메뉴와 메뉴로 시작되는 활동에 대해 HOME 키 를 처리하는 것을 잊지 마십시오 . SEARCH 키도 마찬가지 입니다. 다음은 설명 할 몇 가지 예제 클래스입니다.
다음은 애플리케이션이 파괴 될 때 애플리케이션을 종료하는 루트 활동의 예입니다.
package android.example;
/**
* @author Danny Remington - MacroSolve
*/
public class HomeKey extends CustomActivity {
public void onDestroy() {
super.onDestroy();
/*
* Kill application when the root activity is killed.
*/
UIHelper.killApp(true);
}
}
다음은이를 확장하는 모든 활동에 대해 HOME 키 를 처리하도록 확장 할 수있는 추상 활동입니다 .
package android.example;
/**
* @author Danny Remington - MacroSolve
*/
import android.app.Activity;
import android.view.Menu;
import android.view.MenuInflater;
/**
* Activity that includes custom behavior shared across the application. For
* example, bringing up a menu with the settings icon when the menu button is
* pressed by the user and then starting the settings activity when the user
* clicks on the settings icon.
*/
public abstract class CustomActivity extends Activity {
public void onStart() {
super.onStart();
/*
* Check if the app was just launched. If the app was just launched then
* assume that the HOME key will be pressed next unless a navigation
* event by the user or the app occurs. Otherwise the user or the app
* navigated to this activity so the HOME key was not pressed.
*/
UIHelper.checkJustLaunced();
}
public void finish() {
/*
* This can only invoked by the user or the app finishing the activity
* by navigating from the activity so the HOME key was not pressed.
*/
UIHelper.homeKeyPressed = false;
super.finish();
}
public void onStop() {
super.onStop();
/*
* Check if the HOME key was pressed. If the HOME key was pressed then
* the app will be killed. Otherwise the user or the app is navigating
* away from this activity so assume that the HOME key will be pressed
* next unless a navigation event by the user or the app occurs.
*/
UIHelper.checkHomeKeyPressed(true);
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.settings_menu, menu);
/*
* Assume that the HOME key will be pressed next unless a navigation
* event by the user or the app occurs.
*/
UIHelper.homeKeyPressed = true;
return true;
}
public boolean onSearchRequested() {
/*
* Disable the SEARCH key.
*/
return false;
}
}
다음은 HOME 키 를 처리하는 메뉴 화면의 예입니다 .
/**
* @author Danny Remington - MacroSolve
*/
package android.example;
import android.os.Bundle;
import android.preference.PreferenceActivity;
/**
* PreferenceActivity for the settings screen.
*
* @see PreferenceActivity
*
*/
public class SettingsScreen extends PreferenceActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.layout.settings_screen);
}
public void onStart() {
super.onStart();
/*
* This can only invoked by the user or the app starting the activity by
* navigating to the activity so the HOME key was not pressed.
*/
UIHelper.homeKeyPressed = false;
}
public void finish() {
/*
* This can only invoked by the user or the app finishing the activity
* by navigating from the activity so the HOME key was not pressed.
*/
UIHelper.homeKeyPressed = false;
super.finish();
}
public void onStop() {
super.onStop();
/*
* Check if the HOME key was pressed. If the HOME key was pressed then
* the app will be killed either safely or quickly. Otherwise the user
* or the app is navigating away from the activity so assume that the
* HOME key will be pressed next unless a navigation event by the user
* or the app occurs.
*/
UIHelper.checkHomeKeyPressed(true);
}
public boolean onSearchRequested() {
/*
* Disable the SEARCH key.
*/
return false;
}
}
다음 은 앱 에서 HOME 키 를 처리하는 도우미 클래스의 예입니다 .
package android.example;
/**
* @author Danny Remington - MacroSolve
*
*/
/**
* Helper class to help handling of UI.
*/
public class UIHelper {
public static boolean homeKeyPressed;
private static boolean justLaunched = true;
/**
* Check if the app was just launched. If the app was just launched then
* assume that the HOME key will be pressed next unless a navigation event
* by the user or the app occurs. Otherwise the user or the app navigated to
* the activity so the HOME key was not pressed.
*/
public static void checkJustLaunced() {
if (justLaunched) {
homeKeyPressed = true;
justLaunched = false;
} else {
homeKeyPressed = false;
}
}
/**
* Check if the HOME key was pressed. If the HOME key was pressed then the
* app will be killed either safely or quickly. Otherwise the user or the
* app is navigating away from the activity so assume that the HOME key will
* be pressed next unless a navigation event by the user or the app occurs.
*
* @param killSafely
* Primitive boolean which indicates whether the app should be
* killed safely or quickly when the HOME key is pressed.
*
* @see {@link UIHelper.killApp}
*/
public static void checkHomeKeyPressed(boolean killSafely) {
if (homeKeyPressed) {
killApp(true);
} else {
homeKeyPressed = true;
}
}
/**
* Kill the app either safely or quickly. The app is killed safely by
* killing the virtual machine that the app runs in after finalizing all
* {@link Object}s created by the app. The app is killed quickly by abruptly
* killing the process that the virtual machine that runs the app runs in
* without finalizing all {@link Object}s created by the app. Whether the
* app is killed safely or quickly the app will be completely created as a
* new app in a new virtual machine running in a new process if the user
* starts the app again.
*
* <P>
* <B>NOTE:</B> The app will not be killed until all of its threads have
* closed if it is killed safely.
* </P>
*
* <P>
* <B>NOTE:</B> All threads running under the process will be abruptly
* killed when the app is killed quickly. This can lead to various issues
* related to threading. For example, if one of those threads was making
* multiple related changes to the database, then it may have committed some
* of those changes but not all of those changes when it was abruptly
* killed.
* </P>
*
* @param killSafely
* Primitive boolean which indicates whether the app should be
* killed safely or quickly. If true then the app will be killed
* safely. Otherwise it will be killed quickly.
*/
public static void killApp(boolean killSafely) {
if (killSafely) {
/*
* Notify the system to finalize and collect all objects of the app
* on exit so that the virtual machine running the app can be killed
* by the system without causing issues. NOTE: If this is set to
* true then the virtual machine will not be killed until all of its
* threads have closed.
*/
System.runFinalizersOnExit(true);
/*
* Force the system to close the app down completely instead of
* retaining it in the background. The virtual machine that runs the
* app will be killed. The app will be completely created as a new
* app in a new virtual machine running in a new process if the user
* starts the app again.
*/
System.exit(0);
} else {
/*
* Alternatively the process that runs the virtual machine could be
* abruptly killed. This is the quickest way to remove the app from
* the device but it could cause problems since resources will not
* be finalized first. For example, all threads running under the
* process will be abruptly killed when the process is abruptly
* killed. If one of those threads was making multiple related
* changes to the database, then it may have committed some of those
* changes but not all of those changes when it was abruptly killed.
*/
android.os.Process.killProcess(android.os.Process.myPid());
}
}
}
killApp()Google에서 예측할 수없는 동작으로 이어질 것이라고 지적 했으므로 프로덕션 애플리케이션은에 표시된 코드를 호출해서는 안됩니다 .
예! 애플리케이션이 더 이상 백그라운드에서 실행되지 않도록 가장 확실하게 닫을 수 있습니다. 다른 사람들이 언급했듯이 finish()Google에서 권장하는 방법은 프로그램이 실제로 닫혔다는 것을 의미하지 않습니다.
System.exit(0);
그러면 백그라운드에서 아무것도 실행되지 않고 애플리케이션이 종료됩니다. 그러나 이것을 현명하게 사용하고 파일을 열어 두거나 데이터베이스 핸들을 열어 두지 마십시오. 이러한 일은 일반적으로 finish()명령 을 통해 정리됩니다 .
나는 개인적으로 응용 프로그램에서 나가기를 선택할 때 싫어하고 실제로 나가지 않습니다.
이것이 내가 한 방법입니다.
그냥 넣어
Intent intent = new Intent(Main.this, SOMECLASSNAME.class);
Main.this.startActivityForResult(intent, 0);
활동을 여는 메서드 내부에 넣은 다음 앱을 닫도록 설계된 SOMECLASSNAME 메서드 내부에 넣습니다.
setResult(0);
finish();
그리고 다음을 Main 클래스에 넣었습니다.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == 0) {
finish();
}
}
오랜 시간이 지난 후 내 자신의 질문에 대답하기 위해 (CommonsWare가 가장 인기있는 대답에 대해 우리가 이것을하지 말아야한다고 언급했기 때문에) :
앱을 종료하고 싶을 때 :
FLAG_ACTIVITY_CLEAR_TOP(이후에 시작된 다른 모든 활동을 종료합니다. 즉, 모두)로 시작합니다. 이 활동을 활동 스택에 넣으십시오 (사전에 어떤 이유로 완료하지 마십시오).finish()이 활동을 부른다이것은 나에게 아주 잘 작동합니다.
버튼 EXIT 클릭에이 코드를 작성하십시오.
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("LOGOUT", true);
startActivity(intent);
그리고 MainActivity.class 의 onCreate () 메서드에서 아래 코드를 첫 번째 줄로 작성하십시오.
if (getIntent().getBooleanExtra("LOGOUT", false))
{
finish();
}
프레임 워크 API를 사용하는 것은 불가능합니다. 프로세스를 제거하거나 메모리에 유지해야하는시기를 결정하는 것은 운영 체제 (Android)의 재량입니다. 이는 효율성을위한 이유입니다. 사용자가 앱을 다시 시작하기로 결정하면 메모리에로드 할 필요없이 이미 앱이있는 것입니다.
그래서 아니요, 낙담 할 뿐만 아니라 불가능 합니다.
앱 종료 방법 :
방법 1 :
을 호출 finish();하고 재정의 onDestroy();합니다. 다음 코드를 입력하십시오 onDestroy().
System.runFinalizersOnExit(true)
또는
android.os.Process.killProcess(android.os.Process.myPid());
방법 2 :
public void quit() {
int pid = android.os.Process.myPid();
android.os.Process.killProcess(pid);
System.exit(0);
}
방법 3 :
Quit();
protected void Quit() {
super.finish();
}
방법 4 :
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("EXIT", true);
startActivity(intent);
if (getIntent().getBooleanExtra("EXIT", false)) {
finish();
}
방법 5 :
때때로 호출 finish()은 전체 애플리케이션이 아닌 현재 활동 만 종료합니다. 그러나 이에 대한 해결 방법이 있습니다. 를 시작할 때마다을 activity사용하여 시작하십시오 startActivityForResult(). 전체 앱을 닫으려면 다음과 같이 할 수 있습니다.
setResult(RESULT_CLOSE_ALL);
finish();
그런 다음 모든 활동의 onActivityResult(...)콜백을 정의 activity하여 RESULT_CLOSE_ALL값 이 반환 되면 다음도 호출합니다 finish().
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(resultCode){
case RESULT_CLOSE_ALL:{
setResult(RESULT_CLOSE_ALL);
finish();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
이것이 Windows Mobile이 작동하는 방식입니다. 이 문제에 대해 Microsoft가 말한 내용은 다음과 같습니다.
http://blogs.msdn.com/windowsmobile/archive/2006/10/05/The-Emperor-Has-No-Close.aspx (내가 모든 블로그 게시물 2006 방법의 제목을 기억 슬픈입니까? Google에서 "황제는 가까이 있지 않다"를 검색하여 기사를 찾았습니다 lol)
요컨대 :
앱이 백그라운드에있는 동안 시스템에 더 많은 메모리가 필요한 경우 앱을 닫습니다. 그러나 시스템에 더 많은 메모리가 필요하지 않은 경우 앱은 RAM에 남아 있으며 다음에 사용자가 필요로 할 때 빠르게 돌아올 수 있습니다.
O'Reilly의이 질문에 대한 많은 의견은 Android가 사용중인 메모리가 필요할 때만 한동안 사용되지 않은 응용 프로그램을 종료하면서 Android가 거의 동일한 방식으로 작동한다고 제안합니다.
이것은 표준 기능이므로 강제 종료로 동작을 변경하면 사용자 경험이 변경됩니다. 많은 사용자가 Android 앱을 부드럽게 닫는 데 익숙해 져서 다른 작업을 수행 한 후 다시 돌아올 의도로 앱을 닫으면 애플리케이션의 상태가 재설정되거나 시간이 더 오래 걸린다는 사실에 다소 실망 할 수 있습니다. 열기 위해. 나는 그것이 예상되는 것이므로 표준 행동을 고수 할 것입니다.
활동 에서 finish()메서드를 호출하면 현재 활동에 원하는 효과가 있습니다.
위의 모든 답변이 내 앱에서 잘 작동하지 않습니다.
여기 내 작업 코드가 있습니다.
종료 버튼 :
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
ComponentName cn = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(cn);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
mainIntent.putExtra("close", true);
startActivity(mainIntent);
finish();
이 코드는 다른 모든 활동을 닫고 MainActivity에서 MainActivity를 맨 위에 가져 오는 것입니다.
if( getIntent().getBooleanExtra("close", false)){
finish();
}
코드 아래를 복사하고 첫 번째 활동 태그 아래에 AndroidManifest.xml 파일을 붙여 넣습니다.
<activity
android:name="com.SplashActivity"
android:clearTaskOnLaunch="true"
android:launchMode="singleTask"
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"
/>
</intent-filter>
</activity>
또한 AndroidManifest.xml 파일의 활동 태그 아래에 아래 코드를 모두 추가하십시오.
android:finishOnTaskLaunch="true"
onBackPressed에 다음 코드를 작성하면됩니다.
@Override
public void onBackPressed() {
// super.onBackPressed();
//Creating an alert dialog to logout
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setMessage("Do you want to Exit?");
alertDialogBuilder.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
}
});
alertDialogBuilder.setNegativeButton("No",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
}
});
//Showing the alert dialog
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
내 안드로이드 기기의 홈 화면으로 돌아가고 싶었 기 때문에 간단히 다음을 사용했습니다.
moveTaskToBack(true);
public class CloseAppActivity extends AppCompatActivity
{
public static final void closeApp(Activity activity)
{
Intent intent = new Intent(activity, CloseAppActivity.class);
intent.addCategory(Intent.CATEGORY_HOME);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
activity.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
finish();
}
}
그리고 매니페스트에서 :
<activity
android:name=".presenter.activity.CloseAppActivity"
android:noHistory="true"
android:clearTaskOnLaunch="true"/>
그러면 전화를하시면 CloseAppActivity.closeApp(fromActivity)신청이 종료됩니다.
finish (); 호출하여 OnClick 버튼 또는 메뉴에서
case R.id.menu_settings :
finish(); return true;
finish()앱을 죽이지 않습니다. 이전 의도로 돌아가거나 앱을 배경으로 할 수 있습니다.