Android 애플리케이션을 닫는 방법은 무엇입니까? 더 이상 백그라운드에서

더 이상 백그라운드에서 실행되지 않도록 애플리케이션을 닫고 싶습니다.

그렇게하는 방법? 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());
        }

    }
}


답변

예! 애플리케이션이 더 이상 백그라운드에서 실행되지 않도록 가장 확실하게 닫을 수 있습니다. 다른 사람들이 언급했듯이 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가 가장 인기있는 대답에 대해 우리가 이것을하지 말아야한다고 언급했기 때문에) :

앱을 종료하고 싶을 때 :

  1. 첫 번째 활동 (스플래시 화면 또는 현재 활동 스택의 맨 아래에있는 모든 활동)을 FLAG_ACTIVITY_CLEAR_TOP(이후에 시작된 다른 모든 활동을 종료합니다. 즉, 모두)로 시작합니다. 이 활동을 활동 스택에 넣으십시오 (사전에 어떤 이유로 완료하지 마십시오).
  2. 나는 finish()이 활동을 부른다

이것은 나에게 아주 잘 작동합니다.


답변

버튼 EXIT 클릭에이 코드를 작성하십시오.

Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("LOGOUT", true);
startActivity(intent);

그리고 MainActivity.classonCreate () 메서드에서 아래 코드를 첫 번째 줄로 작성하십시오.

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);
}