プログラムでAndroidアプリケーションを終了する方法


322

プログラムでAndroidアプリケーションを終了するためのコードをいくつか見つけました。onDestroy()で次のコードのいずれかを呼び出すと、アプリケーションが完全に終了しますか?

  1. System.runFinalizersOnExit(true)
    (または)
  2. android.os.Process.killProcess(android.os.Process.myPid());

終了ボタンをクリックした後、アプリケーションをバックグラウンドで実行したくありません。Plsは、これらのコードのいずれかを使用してアプリを終了できることを示唆していますか?その場合、どのコードを使用できますか?Androidでアプリを終了する良い方法はありますか?


ここにはすでにたくさんの投稿があります。stackoverflow.com/search?q=how+to+exit+an+android+app
Mudassir


「System.exit(0);」を使用します アプリを本当に終了したいとき。ユーザーにメッセージを表示した後、回復不可能なエラーでそれを行いました。必要に応じて、AlarmManagerを使用してアプリを自動的に再起動することもできます。参照:blog.janjonas.net/2010-12-20/...
誰かのどこか

回答:


398

API 16以降は、finishAffinityメソッドを使用できます。これは、名前とJavadocの説明から、関連するすべてのアクティビティを閉じるのにかなり近いようです。

this.finishAffinity();

このアクティビティと、現在のタスクで同じアフィニティを持つそのすぐ下のすべてのアクティビティを終了します。これは通常、アプリケーションが別のタスク(アプリケーションが理解するコンテンツタイプのACTION_VIEWからなど)で起動でき、ユーザーが上ナビゲーションを使用して現在のタスクから独自のタスクに切り替えたときに使用されます。この場合、ユーザーが2番目のアプリケーションの他のアクティビティに移動した場合、それらすべてをタスクスイッチの一部として元のタスクから削除する必要があります。

この仕上げでは、前のアクティビティに結果を配信できず、そうしようとすると例外がスローされることに注意してください。


API 21以降、非常によく似たコマンドを使用できます

finishAndRemoveTask();

このタスクのすべてのアクティビティを終了し、最近のタスクリストから削除します。


28
これが正解です。を使用してアプリを完成させるのは良い解決策ではありませんSystem.exit(0);。お返事ありがとうございます!最後に私はまともな解決策を見つけました。
アントニオ

4
API 14に別のソリューションがあるかどうか知っていますか?ありがとう
Script Kitty、

2
アプリを閉じるとき、またはアクティビティライフサイクル内で、各アクティビティを個別にfinish()できます。
sivi 2015年

3
警告!this.finishAffinity()はアプリを閉じてメモリから削除するため、プッシュメッセージなどを受信しません。
Tincho825

7
このソリューションは99%のケースで機能します。ただし、プロセスは破棄されないため、たとえばDaggerはクリアされません。プロセスを強制終了する必要があるこれらのまれなケースでSystem.exit(0)は、私にとって有効な唯一のソリューションです。
スラブ

155
getActivity().finish();
System.exit(0);

これがアプリを終了する最良の方法です。

私にとって最良の解決策。


ええ、素晴らしい作品です!これをMainActivityから呼び出して機能させる必要があります!
mz87 2014年

完璧なソリューション。Androidはメモリ管理に最適であるため、プロセスを終了する必要はありません。ただし、これはアクティビティを終了するためのソリューションを提供するだけでなく、ユーザーの便宜のためにアプリを終了します。
IAmTheSquidward 2015年

本当に完璧なソリューション。多くの問題を修正しました。ありがとう。
superuserdo

26
これは良い解決策ではないと思います。を使用してプログラムを終了するべきではありませんSystem.exit(0);。適切な解決策が@siviによって投稿されました(彼の回答は上記です)
Antonio

13
これは解決策ではなく、アクティビティのスタックがある場合は機能しません
user3290180

46

finishAffinity();

System.exit(0);

アプリケーションfinishAffinity();なしでのみ使用する場合System.exit(0);は終了しますが、割り当てられたメモリは引き続き電話で使用されているため、アプリをクリーンで本当に終了する場合は、両方を使用します。

これは最も簡単な方法であり、どこでも機能し、実際にアプリを終了します。多くのアクティビティを開いたままでも問題なくすべて終了します。

ボタンクリックの例

public void exitAppCLICK (View view) {

    finishAffinity();
    System.exit(0);

}

または、何か良いものが必要な場合は、3つのボタンを備えたアラートダイアログの例YES NOおよびCANCEL

// alertdialog for exit the app
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);

// set the title of the Alert Dialog
alertDialogBuilder.setTitle("your title");

// set dialog message
alertDialogBuilder
        .setMessage("your message")
        .setCancelable(false)
        .setPositiveButton("YES"),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog,
                                        int id) {
                        // what to do if YES is tapped
                        finishAffinity();
                        System.exit(0);
                    }
                })

        .setNeutralButton("CANCEL"),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog,
                                        int id) {
                        // code to do on CANCEL tapped
                        dialog.cancel();
                    }
                })

        .setNegativeButton("NO"),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog,
                                        int id) {
                        // code to do on NO tapped
                        dialog.cancel();
                    }
                });

AlertDialog alertDialog = alertDialogBuilder.create();

alertDialog.show();

3
これは正解です、私は探していました。感謝
ドリフトウッド

アプリでFCMまたはバックグラウンドタスクを使用した場合、問題はありませんか?
roghayeh hosseini

これは、アプリケーションをメモリから消去するために必要なものでした
A1m

使用しないでくださいSystem.exit(0);そのメモリを解放しないでください。必要に応じてシステムが実行します。これは意図された動作です。
crgarridos

30

アプリケーションを強制終了する必要がある場合は、真剣に考えてください。リソースを解放する場所とタイミングをOSに認識させてみませんか?

それ以外の場合は、本当に確信がある場合は、

finish();

@dave appletonのコメントへの反応として:最初に投稿された大きな質問と回答の組み合わせ@gabrielを読んでください:アプリケーションの終了は不快に感じられますか?

さて、私たちがそれを持っていると仮定すると、ここでの質問にはまだ答えがあります。つまり、終了して何かをする場合に必要なコードはfinish()です。もちろん、複数のアクティビティなどを行うことができますが、それは重要ではありません。いくつかのユースケースで実行してみましょう

  1. メモリ使用量が原因でユーザーがすべてを終了できるようにして、「バックグラウンドで実行されていませんか?ダウトフル。ユーザーに特定のアクティビティをバックグラウンドで停止させ、OSに不要なリソースを強制終了させます。
  2. ユーザーがアプリの前のアクティビティにアクセスしないようにしたいですか?まあ、そうしないように設定するか、追加のオプションが必要です。ほとんどの場合、back = previous-activityが機能する場合、ユーザーは何か他のことをしたいのであれば、家を押すだけではありませんか?
  3. なんらかのリセットが必要な場合は、アプリケーションが終了したかどうか、またどのように終了したかを確認できます。アクティビティが再びフォーカスされた場合は、元の場所から再開するのではなく、新しい画面を表示してアクションを実行できます。

だから、最終的には、勿論、finish()everthing殺すことはありませんが、それはまだあなたが私が思う必要なツールです。「すべての活動を殺す」ためのユースケースがある場合、私はそれをまだ見つけていません。


30
呼び出しfinish()てもアプリケーションは終了しません。finish()は常に使用されCall this when your activity is done and should be closed.ます。「戻る」ボタンを押すのと同じ効果です。
Tanner Perrien

終了するとアクティビティが終了します。これはアプリを殺すのとどう違うのですか?
ナンヌ

「ではない」の「終了」または「殺害」に問題はありActivityませんApplication。たとえば、新しいアクティビティを開始して、ユーザーにいくつかの情報を表示することができます。タイムアウト後または「OK」を押すfinish()と、呼び出しアクティビティに戻るために呼び出すことができます。
Tanner Perrien

42
ほとんどのAndroidアプリケーションには複数のアクティビティがあります。
CommonsWare

4
@Nanne-ロック画面は、すべてのアクティビティを停止したい場合の例です。バンキングアプリにログインするとします。ユーザーからの操作がない一定の時間の後、ロック画面が起動します。ロック画面から戻るボタンが押された場合は、すべてのアクティビティを停止する必要があります。
Jabari 2013年

19

場合によってはアプリケーションをkillすべきだと思います。たとえば、ログイン後にのみ使用できるアプリがあります。ログインアクティビティには、「ログイン」と「キャンセル」の2つのボタンがあります。「キャンセル」ボタンをクリックすると、間違いなく「アプリを終了する」という意味になります。アプリがバックグラウンドで動作することを望んでいる人はいません。したがって、アプリをシャットダウンする必要がある場合があることに同意します。


2
私はこのユースケースに完全に同意します。また、特定の場所で利用可能である必要があり、ユーザーがその場所にいない場合は閉じることをお勧めする、安全なアプリも検討してください。私は何をしますか?
Sydwell 2014年

18

を作成し、ExitActivityマニフェストで宣言します。そしてExitActivity.exit(context)、アプリの終了を要求します。

public class ExitActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        finish();
    }

    public static void exit(Context context) {
        Intent intent = new Intent(context, ExitActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        context.startActivity(intent);
    }

}

これは最も投票された回答ですが、ハックです。onCreateでfinishを呼び出すと、すべてではないにしても、ほとんどのデバイスで問題が発生します。
DoruChidean

うーん、それはハックですが、グリッチではありません。最初にexit()を呼び出します。これは、すべてのアクティビティの上部にクリアトップとタスクがあり、それ自体が終了します。ここであなたは終了します。
vivek

1
マニフェストでこのクラスを宣言することを忘れないでください。ただし、巧妙なハックの場合は+1。
Taslim Oseni

これはうまくいった!投票
TuanDPH

17

android SampleActivity.this.finish();で終了するアプリケーションはありません。現在のアクティビティを終了します。

あるアクティビティから別のアクティビティに切り替えたら、前のアクティビティを終了してください

Intent homeintent = new Intent(SampleActivity.this,SecondActivity.class);
startActivity(homeintent);
SampleActivity.this.finish();

13

まず、このアプローチには最小API 16が必要です。

この問題をより広く解決するために、このソリューションを3つの部分に分割します。

1. アクティビティでアプリケーションを終了する場合は、次のコードスニペットを使用します。

if(Build.VERSION.SDK_INT>=16 && Build.VERSION.SDK_INT<21){
    finishAffinity();
} else if(Build.VERSION.SDK_INT>=21){
    finishAndRemoveTask();
}

2. アクティビティにアクセスできるアクティビティクラス以外のアプリケーションを終了する場合は、次のコードスニペットを使用します。

if(Build.VERSION.SDK_INT>=16 && Build.VERSION.SDK_INT<21){
    getActivity().finishAffinity();
} else if(Build.VERSION.SDK_INT>=21){
    getActivity().finishAndRemoveTask();
}

3.非Activityクラスのアプリケーションを終了し、ServiceなどのActivityにアクセスできない場合は、BroadcastReceiverを使用することをお勧めします。このアプローチをプロジェクトのすべてのアクティビティに追加できます。

LocalBroadcastManagerおよびBroadcastReceiverインスタンス変数を作成します。必要に応じて、getPackageName()+ "。closeapp"を置き換えることができます。

LocalBroadcastManager mLocalBroadcastManager;
BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent.getAction().equals(getPackageName()+".closeapp")){
            if(Build.VERSION.SDK_INT>=16 && Build.VERSION.SDK_INT<21){
                finishAffinity();
            } else if(Build.VERSION.SDK_INT>=21){
                finishAndRemoveTask();
            }
        }
    }
};

これらをActivityのonCreate()メソッドに追加します。

mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
IntentFilter mIntentFilter = new IntentFilter();
mIntentFilter.addAction(getPackageName()+".closeapp");
mLocalBroadcastManager.registerReceiver(mBroadcastReceiver, mIntentFilter);

また、ActivityのonDestroy()メソッドでunregisterレシーバーを呼び出すことを忘れないでください

mLocalBroadcastManager.unregisterReceiver(mBroadcastReceiver);

アプリケーションを終了するには、Serviceを拡張するPlayServiceクラスで使用するLocalBroadcastManagerを使用してブロードキャストを送信する必要があります。

LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(PlayService.this);
localBroadcastManager.sendBroadcast(new Intent(getPackageName() + ".closeapp"));

10

finishAndRemoveTask ()API 21から使用できます

public void finishAndRemoveTask()

このタスクのすべてのアクティビティを終了し、最近のタスクリストから削除します。


8

それはあなたがあなたのアプリをどれくらい速く閉じたいかによります。

アプリを安全に閉じる方法は、finishAffinity();です。

すべてのプロセスが処理を完了した後、アプリを閉じます。これには時間がかかる場合があります。この方法でアプリを閉じ、しばらくしてから再起動すると、新しいアプリケーションが同じプロセスで実行される可能性があります。古いアプリケーションのすべての未完了のプロセスとシングルトンオブジェクト。

確実にしたい場合は、アプリが完全に閉じていることをSystem.exit(0);を使用してください

これにより、アプリがすぐに閉じられます。ただし、アプリが開いているファイルに損傷を与えたり、共有設定の編集が完了しない可能性があります。したがって、これは慎重に使用してください。

ウォッチドッグを長時間実行するタスクと組み合わせて使用​​すると、さまざまな方法の影響を確認できます。

new ANRWatchDog(2000).setANRListener(new ANRWatchDog.ANRListener() {
    public void onAppNotResponding(ANRError error) {
        MainActivity.this.finishAffinity();
        System.exit(0);
    }
}).start();
for(int i = 0; i < 10; ++i){
    --i;
}

これにより、ANRダイアログなどを表示せずに2秒後にアプリが強制終了されます。System.exit(0)を削除し、このコードを実行して、アプリを閉じた後に再起動すると、無限ループがまだ実行されているため、奇妙な動作が発生します。


8

にいるfinish()場合Activity、またはにいるgetActivity().finish()場合は、使用することをお勧めしますFragment

アプリを完全に終了する場合は、次を使用します。

getActivity().finish();
System.exit(0);

6

アプリケーションを終了する簡単でシンプルな方法

Intent homeIntent = new Intent(Intent.ACTION_MAIN);
homeIntent.addCategory(Intent.CATEGORY_HOME);
homeIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(homeIntent);

これは単にホーム画面を表示するのですか、それとも実際にアプリを終了するのですか?
ルパッタビ

6

堅牢でシンプルなコードが必要です。このソリューションは、古いデバイスと新しいデバイスで機能します。

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        getActivity().finishAffinity();
    } else{
        getActivity().finish();
        System.exit( 0 );
    }

5

あなたが探しているのはこれだと思います

activity.moveTaskToBack(Boolean nonRoot);


5

@MobileMateoに似ていますが、Kotlinにあります

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
    this.finishAffinity()
} else{
    this.finish()
    System.exit(0)
}

4

これが眉をひそめているかどうかはわかりませんが、これが私のやり方です...

ステップ1-通常、グローバルにアクセスするメソッドと変数を含むクラスがあります。この例では、これを「App」クラスと呼びます。アプリが持つ各アクティビティの静的なActivity変数をクラス内に作成します。次に、「close」と呼ばれる静的メソッドを作成しますfinish()これらのメソッドがnullでない場合、それらのActivity変数ごとにメソッドを実行します。メイン/親アクティビティがある場合は、最後に閉じます。

public class App
{
    ////////////////////////////////////////////////////////////////
    // INSTANTIATED ACTIVITY VARIABLES
    ////////////////////////////////////////////////////////////////

        public static Activity activity1;
        public static Activity activity2;
        public static Activity activity3;

    ////////////////////////////////////////////////////////////////
    // CLOSE APP METHOD
    ////////////////////////////////////////////////////////////////

        public static void close()
        {
            if (App.activity3 != null) {App.activity3.finish();}
            if (App.activity2 != null) {App.activity2.finish();}
            if (App.activity1 != null) {App.activity1.finish();}
        }
}

ステップ2-各アクティビティで、onStart()およびonDestroy()メソッドをオーバーライドします。ではonStart()、あなたのアプリケーションクラスのstatic変数を設定するには、「に等しいですthis」。でonDestroy()、に設定しnullます。たとえば、「Activity1」クラスでは:

@Override
public void onStart()
{
    // RUN SUPER | REGISTER ACTIVITY AS INSTANTIATED IN APP CLASS

        super.onStart();
        App.activity1 = this;
}

@Override
public void onDestroy()
{
    // RUN SUPER | REGISTER ACTIVITY AS NULL IN APP CLASS

        super.onDestroy();
        App.activity1 = null;
}

ステップ3-アプリを閉じたいときは、App.close()、どこからでもができます。インスタンス化されたアクティビティはすべて終了します!(例のように)アクティビティを閉じるだけでアプリ自体を強制終了しないので、Androidはそこから引き継いで必要なクリーンアップを自由に実行できます。

繰り返しになりますが、これが何らかの理由で眉をひそめられるかどうかはわかりません。もしそうなら、私はそれがなぜであり、どのようにそれが改善されることができるかについてのコメントを読みたいです!


興味深いことに、私も他の経験豊富なAndroid開発者がこれについて考えたことに興味があります。
Rudi Kershaw 2014

4
あなたの活動への参照を維持することにより、あなたは実際にメモリをリークしています!詳細については、こちらをご覧ください。
Managarm 2014年

@Managarmその投稿の背後にある前提は、プロセス(この場合はアクティビティ)が破棄された後でも静的変数が残ることです。ただし、適切なハウスクリーニングが行われた場合は問題ありません。そのため、アクティビティのonDestroy()メソッドで参照を無効にする理由はここにあります。
Jabari 2014年

@Jabariああ、onDestroyの部分を逃した。その場合、それは問題にはなりませんが、ベストプラクティスではありません。
Managarm 2014年

1
問題なく動作しました。以下のためにapi>=16使用finishAffinity()他に、このメソッドを使用します。
Nobody氏

4

アプリケーションを終了すると、眉をひそめますか?。このリンクを通過します。それはあなたの質問に答えます。システムはアプリケーションを強制終了します。

2つのアクティビティAとBがあるとします。AからBに移動します。戻るボタンをクリックすると、アクティビティBがバックスタックからポップされて破棄されます。バックスタックアクティビティAの前のアクティビティがフォーカスされます。

アプリケーションを強制終了するタイミングはシステムに任せる必要があります。

パブリックボイド finish()

アクティビティが完了し、閉じる必要があるときにこれを呼び出します。

多くの活動があるとします。アクションバーを使用できます。ホームアイコンをクリックすると、アプリケーションのMainActivityにナビゲートします。MainActivityで[戻る]ボタンをクリックして、アプリケーションを終了します。


3

アプリケーションを終了するには、以下を使用できます。

getActivity().finish();
Process.killProcess(Process.myPid());
System.exit(1);

また、サービスを停止するには、次のメソッドを呼び出します。

private void stopServices() {        
    final ActivityManager activityManager = SystemServices.getActivityManager(context);
    final List<ActivityManager.RunningServiceInfo> runningServices = activityManager.getRunningServices(Integer.MAX_VALUE);
    final int pid = Process.myPid();
    for (ActivityManager.RunningServiceInfo serviceInfo : runningServices) {
        if (serviceInfo.pid == pid && !SenderService.class.getName().equals(serviceInfo.service.getClassName())) {
            try {
                final Intent intent = new Intent();
                intent.setComponent(serviceInfo.service);
                context.stopService(intent);
            } catch (SecurityException e) { 
                 // handle exception
            }
        }
    }
}

2

これは非常に遅くなる可能性があり、ガイドラインに従って、ライフサイクルプロセスを自分で処理することは想定されていません(OSがそれを行うため)。すべてのアクティビティのブロードキャストレシーバーを " finish()"で登録し、onReceive() 終了する場合はいつでも、すべてのアクティビティをシャットダウンする必要があることを示すインテントを単純に渡すことができます。ただし、必ず実行してください " onDestroy()メソッドでレシーバーを登録解除します。


1

これは適切な決定ではありません。Androidのアプリケーション処理の原則に反するためです。どうしても避けられない場合を除いて、Androidはプロセスを強制終了しません。これにより、アプリの起動が速くなり、常にメモリに保持されます。したがって、アプリケーションのプロセスを強制終了するには、非常に特別な理由が必要です。


4
アプリケーションからサインアウトするには、アプリを本当に強制終了する必要があります。そのサインアウト後に死亡したアプリを確実にする方法があるはず
anonim

1

ボタンクリックでアプリを終了するための正しい正確なソリューションは、以下のコードを使用することです。

// On Button Back Pressedイベント

public void onBackPressed()
{ 
   moveTaskToBack(true);
   finish();
}

これは、アプリ全体ではなく、現在のAndroidコンポーネント(アクティビティなど)です
Laogeodritt

アプリはバックグラウンドでのみ送信されます
Kumar Gaurav

1

Kotlinを使用している場合、アプリを終了する適切な方法System.exit()は、組み込みの方法です

exitProcess(0)

ドキュメントを参照してください。

0パラメータとしての数値は、出口が意図されたものであり、エラーが発生しなかったことを意味します。


0

これは何でも殺すでしょう;)

int p = android.os.Process.myPid();
android.os.Process.killProcess(p);


0

Androidのロジックを壊したり、既存のアクティビティにコードを追加したり、エクストラを渡したりせずに、アクティビティからアプリケーションを終了する最も簡単な方法は次のとおりです。

public static void quitApplication (Activity currentActivity) {
    Intent intent = new Intent (currentActivity, QuitApplicationActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);

    currentActivity.startActivity (intent);
    currentActivity.finish ();
}

QuitApplicationActivityビーイング:

public class QuitApplicationActivity extends AppCompatActivity {

    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate (savedInstanceState);

        finish ();
    }
}

0

@Siviの答えはアプリを閉じます。ただし、戻り時に、いくつかの子アクティビティーがある場合、別の未完了のアクティビティーが開かれる可能性があります。noHistory:trueアクティビティに追加したので、戻ったときのアプリはMainActivityから開始します。

<activity 
      android:name=".MainActivity"
      android:noHistory="true">
</activity>

0

アプリを終了する残忍な方法のリストに1つ追加するだけです。

Process.sendSignal(Process.myPid(), Process.SIGNAL_KILL);


Process.killProcess(Process.myPid())同じことを行いますが、短くなります
ivan8m8

-1

完全なアプリを終了できます。したがって

Intent intent = getBaseContext().getPackageManager()
             .getLaunchIntentForPackage(getBaseContext().getPackageName());
intent .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

100%動作します。がんばって!


1
この質問に対する答えのようには見えません!
Al-Mothafar 2017

-4

戻るキーを押すときにfinish()を使用するだけonKeypressed()


4
finish()はアクティビティを閉じますが、確実にアプリ全体を閉じるわけではありません。
2Dee、2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.