web-dev-qa-db-ja.com

Androidでアプリケーションを閉じてホーム画面を起動します

私には2つの異なる活動があります。最初のものは2番目のものを起動します。 2番目のアクティビティでは、アプリケーションを強制的に閉じるためにSystem.exit(0)を呼び出しますが、アプリケーションがホーム画面に戻るのではなく、最初のアクティビティが自動的に表示されます。これを回避し、アプリケーションをホーム画面に戻すにはどうすればよいですか?

75
Arutha

本当にアプリケーションを終了しないことを考えるべきです。これは、Androidアプリの通常の動作方法ではありません。

45
Romain Guy

短い答え:moveTaskToBack(true)の代わりに ActivitySystem.exit() を呼び出します。これにより、ユーザーが再度使用するまでアプリケーションが非表示になります。

長い答えは、別の質問から始まります:なぜアプリケーションを殺したいのですか?

Android OSはメモリ管理やプロセスなどを処理するので、私のアドバイスはAndroidがこれについて心配することです。ユーザーがアプリケーションを終了したい場合、ホームボタンを押すと、アプリケーションは事実上消えます。後で電話がより多くのメモリを必要とする場合、OSはアプリケーションを終了します。

ライフサイクルイベントに適切に応答する である限り、あなたもユーザーも、アプリケーションがまだ実行されているかどうかを気にする必要はありません。

したがって、アプリケーションを非表示にする場合は、moveTaskToBack()を呼び出して、Androidにそれを強制終了するタイミングを決定させます。

88
Dave Webb

これを実現する最も簡単な方法を以下に示します(Androidのネイティブメモリ管理に影響を与えることなく、プロセスの強制終了はありません)。

  1. このインテントを使用してアクティビティを起動します。

    Intent intent = new Intent(this, FinActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(intent);
    finish();
    
  2. ターゲットアクティビティFinActivity.classで、onCreateのfinish()を呼び出します。

手順の説明:

  1. 他のすべてのアクティビティ(FLAG_ACTIVITY_CLEAR_TOP)を消去するインテントを作成し、現在のアクティビティを削除します。

  2. アクティビティはそれ自体を破壊します。別の方法は、finActivityでスプラッシュスクリーンを作成できることです。これはオプションです。

53
jordi

Androidには、ドキュメントごとにアプリケーションを安全に閉じるためのメカニズムがあります。終了する最後のアクティビティ(通常、アプリケーションの起動時に最初に起動したメインアクティビティ)では、onDestroy()メソッドに数行を配置するだけです。 System.runFinalizersOnExit(true)を呼び出すと、アプリケーションの終了時にすべてのオブジェクトがファイナライズされ、ガベージコレクションされます。例えば:

public void onDestroy() {
    super.onDestroy();

    /*
     * Notify the system to finalize and collect all objects of the
     * application on exit so that the process running the application can
     * be killed by the system without causing issues. NOTE: If this is set
     * to true then the process will not be killed until all of its threads
     * have closed.
     */
    System.runFinalizersOnExit(true);

    /*
     * Force the system to close the application down completely instead of
     * retaining it in the background. The process that runs the application
     * will be killed. The application will be completely created as a new
     * application in a new process if the user starts the application
     * again.
     */
    System.exit(0);
}

最後に、AndroidはアプリケーションにHOMEキーイベントを通知しないため、HOMEキーが押されたときにアプリケーションを閉じることはできません。 Androidは、HOMEキーイベント自体を予約するため、開発者はユーザーがアプリケーションを離れることを防ぐことができません。

20

また、最初のアクティビティのタグで noHistory = "true"を指定するか、2番目のアクティビティを開始するとすぐに最初のアクティビティを終了することができます(Davidが述べたように)。

知る限り、「強制終了」は、アプリケーションが実行されているJVMをホストするプロセスを強制終了し、System.exit()はアプリケーションインスタンスを実行しているJVMを終了します。どちらも突然の終了の形式であり、通常のアプリケーションフローにはお勧めできません。

プログラムが引き受けるかもしれない論理フローをカバーするために例外をキャッチするのと同じように、お勧めできません。

9
Samuh

このメソッドを使用してアクティビティを閉じます!

public static void closeAllBelowActivities(Activity current) {
    boolean flag = true;
    Activity below = current.getParent();
    if (below == null)
        return;
    System.out.println("Below Parent: " + below.getClass());
    while (flag) {
        Activity temp = below;
        try {
            below = temp.getParent();
            temp.finish();
        } catch (Exception e) {
            flag = false;
        }
    }
}
9
amsurana

2番目のアクティビティを起動すると、finish()最初のアクティビティがすぐに開始されます。

startActivity(new Intent(...));
finish();
8
David Hedlund

Android.os.Process.killProcess(Android.os.Process.myPid());は正常に機能しますが、Androidプラットフォームにメモリ管理を心配させることをお勧めします:-)

6
Arnab

finishメソッドを使用します。これは、よりシンプルで簡単な方法です。

this.finish();
4
Nikhil

System.exit()は実行できません。安全ではありません。

これを行うことができます:Process.killProcess(Process.myPid());

4
Cytown

私はこれを使用します:

1)親アクティビティは、メソッド「startActivityForResult」でセカンダリアクティビティを呼び出します

2)終了するセカンダリアクティビティ:

int exitCode = 1; // Select the number you want
setResult(exitCode);
finish();

3)そして、親アクティビティでメソッド「onActivityResult」をオーバーライドします。

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    int exitCode = 1;
    if(resultCode == exitCode) {
        super.setResult(exitCode); // use this if you have more than 2 activities
        finish();
    }
}

これは私には問題ありません。

4
molda

永続的なソケット接続を使用するアプリケーションを使用する場合、finish()メソッドは接続を解放しないことに注意してください。通常の状況では、finish()が最適なオプションですが、アプリを終了して使用中のすべてのリソースを解放する必要がある場合は、killProcessを使用します。私はそれを使用して問題がありませんでした。

2
PJ420

A> B> C> D> Eのようなアクティビティスタックがあるとします。アクティビティDで、アプリを閉じたいとします。これはあなたがやることです-

閉じたいアクティビティから(アクティビティD)-

Intent intent = new Intent(D.this,A.class);
intent.putExtra("exit", "exit");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);

RootActivity(つまり、基本アクティビティ、ここではアクティビティA)-

@Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if (intent.hasExtra("exit")) {
            setIntent(intent);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (getIntent() != null) {
            if (("exit").equalsIgnoreCase(getIntent().getStringExtra(("exit")))) {
                onBackPressed();
            }
        }
    }

onNewIntentが使用されるのは、アクティビティが生きている場合、それを開始した最初のインテントを取得するためです。新しいものではありません。詳細- ドキュメント

2
Darpan

以下を試してください。わたしにはできる。

ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1); 
ComponentName componentInfo = taskInfo.get(0).topActivity;
am.restartPackage(componentInfo.getPackageName());
2
Sikandar

StartActivityForResultで2番目のアクティビティを開始し、2番目のアクティビティで値を返します。1番目のアクティビティのonActivityResultメソッドで一度メインアプリケーションを閉じます。これはAndroidが行う正しい方法だと思います。

2
Dayerman

あなたは間違っている。アプリケーションを強制終了する方法が1つあります。スーパークラスApplicationを持つクラスでは、killAppなどのフィールドを使用します。 onResume()でスプラッシュスクリーン(最初のアクティビティ)を開始するとき、フィールドkillAppにfalseのパラメーターを設定します。 onResume()が最後に呼び出されたときに持っているすべてのアクティビティで、次のようなものを呼び出します。

if(AppClass.killApp())
    finish();

画面に到達するすべてのアクティビティは、onResume()を呼び出す必要があります。呼び出されたら、フィールドkillAppがtrueであるかどうかを確認する必要があります。 trueの場合、現在のアクティビティはfinish()を呼び出します。完全なアクションを呼び出すには、次の構成を使用します。たとえば、ボタンのアクションでは:

AppClass.setkillApplication(true);
   finish();
   return;
1
Peter

これは、アプリケーションを閉じるためにしたことです。アプリケーションには、基本アクティビティクラスがあり、 "applicationShutDown"という静的フラグを追加しました。アプリケーションを閉じる必要がある場合、trueに設定します。

基本アクティビティonCreateおよびonResumeで、スーパーコールを呼び出した後、このフラグをテストします。 「applicationShutDown」がtrueの場合、現在のアクティビティでfinishを呼び出します。

これは私のために働いた:

protected void onResume() {
    super.onResume();
    if(BaseActivity.shutDownApp)
    {
        finish();
        return;

    }}
1
user1942887

それは実際に静かで簡単です。

これを行う方法は、すべての人が利用できる静的変数にフラグを保存することです。次に、終了時にこのフラグを設定し、すべてのアクティビティでこのフラグをチェックしますonResume。フラグが設定されている場合、そのアクティビティでSystem.exitを発行します。

これにより、すべてのアクティビティがフラグをチェックし、フラグが設定されている場合は正常に閉じます。

1
Mikeghtmare

同様の問題を解決しました。MainActivityがBrowserActivityを起動し、ユーザーがBrowserActivityで[戻る]を押すと、MainActivityに戻らないようにアプリを閉じる必要があります。だから、MainActivityで:

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "sm500_Rmt.MainActivity";
    private boolean m_IsBrowserStarted = false;

そして、OnResumeで:

    @Override
protected void onResume() {
    super.onResume();
    if(m_IsBrowserStarted) {
        Log.w(TAG, "onResume, but it's return from browser, just exit!");
        finish();
        return;
    }
    Log.w(TAG, "onResume");

...次にOnResumeを続行します。そして、BrowserActivityを起動すると:

    Intent intent = new Intent(this, BrowserActivity.class);
    intent.putExtra(getString(R.string.IPAddr), ip);
    startActivity(intent);
    m_IsBrowserStarted = true;

そして、それはうまくいくようです! :-)

0
Sergey Skosyrev

推奨されませんが、これは引き続き使用できます。アプリを終了する必要がある場合は、このソリューションを使用することをお勧めします。

私によると、最良の解決策は、以下のようにアプリ内のすべてのアクティビティを完了することです。

手順1. mainactivityで静的変数を維持します。いう、

public static boolean isQuit = false;

ステップ2.ボタンのクリックイベントで、この変数をtrueに設定します。

mainactivity.isQuit = true;
finish();

ステップ3.そして、アプリケーションのすべてのアクティビティで、以下のonrestartメソッドを使用します。

@Override
protected void onRestart() {
    // TODO Auto-generated method stub
    super.onRestart();
    if(mainactivity.isQuit)
        finish();
}
0
Shankar Agarwal

結果の開始アクティビティを使用して2番目のアクティビティを実行します。

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);

//This line is important
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);

startActivityForResult(intent, REQUEST_CODE);

この関数を最初のアクティビティに追加します。

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(rquestCode == REQUEST_CODE)
        if(resultCode == RESULT_CANCELED)
            finish();
}

そして、これを2番目のアクティビティに追加します。

@Override
public boolean onKeyDown(int keyCode, KeyEvent event)  {
    if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {

        Log.i(TAG, "Back key pressed");
        setResult(RESULT_CANCELED);
        finish();
        return true;
    }
    return super.onKeyDown(keyCode, event);
}
0
piojo