私には2つの異なる活動があります。最初のものは2番目のものを起動します。 2番目のアクティビティでは、アプリケーションを強制的に閉じるためにSystem.exit(0)
を呼び出しますが、アプリケーションがホーム画面に戻るのではなく、最初のアクティビティが自動的に表示されます。これを回避し、アプリケーションをホーム画面に戻すにはどうすればよいですか?
本当にアプリケーションを終了しないことを考えるべきです。これは、Androidアプリの通常の動作方法ではありません。
短い答え:moveTaskToBack(true)
の代わりに Activity
のSystem.exit()
を呼び出します。これにより、ユーザーが再度使用するまでアプリケーションが非表示になります。
長い答えは、別の質問から始まります:なぜアプリケーションを殺したいのですか?
Android OSはメモリ管理やプロセスなどを処理するので、私のアドバイスはAndroidがこれについて心配することです。ユーザーがアプリケーションを終了したい場合、ホームボタンを押すと、アプリケーションは事実上消えます。後で電話がより多くのメモリを必要とする場合、OSはアプリケーションを終了します。
ライフサイクルイベントに適切に応答する である限り、あなたもユーザーも、アプリケーションがまだ実行されているかどうかを気にする必要はありません。
したがって、アプリケーションを非表示にする場合は、moveTaskToBack()
を呼び出して、Androidにそれを強制終了するタイミングを決定させます。
これを実現する最も簡単な方法を以下に示します(Androidのネイティブメモリ管理に影響を与えることなく、プロセスの強制終了はありません)。
このインテントを使用してアクティビティを起動します。
Intent intent = new Intent(this, FinActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
ターゲットアクティビティFinActivity.class
で、onCreate
のfinish()を呼び出します。
手順の説明:
他のすべてのアクティビティ(FLAG_ACTIVITY_CLEAR_TOP)
を消去するインテントを作成し、現在のアクティビティを削除します。
アクティビティはそれ自体を破壊します。別の方法は、finActivityでスプラッシュスクリーンを作成できることです。これはオプションです。
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キーイベント自体を予約するため、開発者はユーザーがアプリケーションを離れることを防ぐことができません。
また、最初のアクティビティのタグで noHistory = "true"を指定するか、2番目のアクティビティを開始するとすぐに最初のアクティビティを終了することができます(Davidが述べたように)。
知る限り、「強制終了」は、アプリケーションが実行されているJVMをホストするプロセスを強制終了し、System.exit()はアプリケーションインスタンスを実行しているJVMを終了します。どちらも突然の終了の形式であり、通常のアプリケーションフローにはお勧めできません。
プログラムが引き受けるかもしれない論理フローをカバーするために例外をキャッチするのと同じように、お勧めできません。
このメソッドを使用してアクティビティを閉じます!
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;
}
}
}
2番目のアクティビティを起動すると、finish()
最初のアクティビティがすぐに開始されます。
startActivity(new Intent(...));
finish();
Android.os.Process.killProcess(Android.os.Process.myPid());
は正常に機能しますが、Androidプラットフォームにメモリ管理を心配させることをお勧めします:-)
finish
メソッドを使用します。これは、よりシンプルで簡単な方法です。
this.finish();
System.exit()は実行できません。安全ではありません。
これを行うことができます:Process.killProcess(Process.myPid());
私はこれを使用します:
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();
}
}
これは私には問題ありません。
永続的なソケット接続を使用するアプリケーションを使用する場合、finish()
メソッドは接続を解放しないことに注意してください。通常の状況では、finish()
が最適なオプションですが、アプリを終了して使用中のすべてのリソースを解放する必要がある場合は、killProcess
を使用します。私はそれを使用して問題がありませんでした。
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が使用されるのは、アクティビティが生きている場合、それを開始した最初のインテントを取得するためです。新しいものではありません。詳細- ドキュメント
以下を試してください。わたしにはできる。
ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
am.restartPackage(componentInfo.getPackageName());
StartActivityForResultで2番目のアクティビティを開始し、2番目のアクティビティで値を返します。1番目のアクティビティのonActivityResultメソッドで一度メインアプリケーションを閉じます。これはAndroidが行う正しい方法だと思います。
あなたは間違っている。アプリケーションを強制終了する方法が1つあります。スーパークラスApplicationを持つクラスでは、killApp
などのフィールドを使用します。 onResume()
でスプラッシュスクリーン(最初のアクティビティ)を開始するとき、フィールドkillApp
にfalseのパラメーターを設定します。 onResume()
が最後に呼び出されたときに持っているすべてのアクティビティで、次のようなものを呼び出します。
if(AppClass.killApp())
finish();
画面に到達するすべてのアクティビティは、onResume()
を呼び出す必要があります。呼び出されたら、フィールドkillApp
がtrueであるかどうかを確認する必要があります。 trueの場合、現在のアクティビティはfinish()
を呼び出します。完全なアクションを呼び出すには、次の構成を使用します。たとえば、ボタンのアクションでは:
AppClass.setkillApplication(true);
finish();
return;
これは、アプリケーションを閉じるためにしたことです。アプリケーションには、基本アクティビティクラスがあり、 "applicationShutDown"という静的フラグを追加しました。アプリケーションを閉じる必要がある場合、trueに設定します。
基本アクティビティonCreateおよびonResumeで、スーパーコールを呼び出した後、このフラグをテストします。 「applicationShutDown」がtrueの場合、現在のアクティビティでfinishを呼び出します。
これは私のために働いた:
protected void onResume() {
super.onResume();
if(BaseActivity.shutDownApp)
{
finish();
return;
}}
それは実際に静かで簡単です。
これを行う方法は、すべての人が利用できる静的変数にフラグを保存することです。次に、終了時にこのフラグを設定し、すべてのアクティビティでこのフラグをチェックしますonResume
。フラグが設定されている場合、そのアクティビティでSystem.exit
を発行します。
これにより、すべてのアクティビティがフラグをチェックし、フラグが設定されている場合は正常に閉じます。
同様の問題を解決しました。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;
そして、それはうまくいくようです! :-)
推奨されませんが、これは引き続き使用できます。アプリを終了する必要がある場合は、このソリューションを使用することをお勧めします。
私によると、最良の解決策は、以下のようにアプリ内のすべてのアクティビティを完了することです。
手順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();
}
結果の開始アクティビティを使用して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);
}