私には2つの異なる活動があります。最初のものは2番目のものを起動します。2番目のアクティビティでは、アプリケーションを強制的に閉じるために呼び出しますSystem.exit(0)
が、アプリケーションがホーム画面に戻る代わりに、最初のアクティビティが自動的に表示されます。これを回避して、アプリケーションをホーム画面に戻すにはどうすればよいですか?
21 に答える
簡単な答え:の代わり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
で、でfinish()を呼び出しますonCreate
。
説明した手順:
(FLAG_ACTIVITY_CLEAR_TOP)
他のすべてのアクティビティを消去し、現在のアクティビティを削除するインテントを作成します。活動はそれ自体を破壊します。別の方法は、finActivityでスプラッシュ画面を作成できることです。これはオプションです。
あなたは本当にアプリケーションを終了しないことを考えるべきです。これは、Androidアプリが通常どのように機能するかではありません。
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が言ったように)。
AFAIK、「force close」は、アプリケーションが実行されている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プラットフォームにメモリ管理について心配させることをお勧めします:-)
System.exit()を実行することはできません。安全ではありません。
これを行うことができます:Process.killProcess(Process.myPid());
メソッドを使用しfinish
ます。これは、より単純で簡単な方法です。
this.finish();
私はこれを使用します:
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
ください。私はそれを使用するのに問題はありませんでした。
startActivityForResultを使用して2番目のアクティビティを開始し、2番目のアクティビティで値を返します。最初のアクティビティのonActivityResultメソッドで、メインアプリケーションを閉じます。これがAndroidの正しいやり方だと思います。
次のことを試してください。わたしにはできる。
ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
am.restartPackage(componentInfo.getPackageName());
あなたは間違っている。アプリケーションを強制終了する方法は1つあります。スーパークラスApplicationのクラスでは、たとえば、いくつかのフィールドを使用しますkillApp
。でスプラッシュ画面(最初のアクティビティ)を開始するときにonResume()
、フィールドにfalseのパラメータを設定しますkillApp
。onResume()
最後に呼び出されたときに行うすべてのアクティビティでは、次のように呼び出します。
if(AppClass.killApp())
finish();
画面に到達しているすべてのアクティビティは、を呼び出す必要がありますonResume()
。呼び出されたら、フィールドkillApp
が真であるかどうかを確認する必要があります。trueの場合、現在のアクティビティはを呼び出しますfinish()
。完全なアクションを呼び出すには、次の構造を使用します。たとえば、ボタンのアクションでは、次のようになります。
AppClass.setkillApplication(true);
finish();
return;
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が使用されるのは、アクティビティが生きている場合、それを開始した最初のインテントを取得するためです。新しいものではありません。詳細については-ドキュメント
実は静かで簡単です。
私がこれを行う方法は、すべての人が利用できる静的変数にフラグを保存することです。次に、終了するときにこのフラグを設定し、すべてのアクティビティでこのフラグをチェックしますonResume
。フラグが設定されている場合は、System.exit
そのアクティビティでを発行します。
そうすれば、すべてのアクティビティがフラグをチェックし、フラグが設定されている場合は正常に閉じます。
これは、アプリケーションを閉じるために行ったことです。私のアプリケーションには、基本アクティビティクラスがあり、「applicationShutDown」という静的フラグを追加しました。アプリケーションを閉じる必要があるときは、trueに設定します。
スーパーコールを呼び出した後の基本アクティビティonCreateとonResumeで、このフラグをテストします。「applicationShutDown」がtrueの場合、現在のアクティビティでfinishを呼び出します。
これは私のために働いた:
protected void onResume() {
super.onResume();
if(BaseActivity.shutDownApp)
{
finish();
return;
}}
結果の開始アクティビティを使用して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);
}
推奨されていませんが、引き続き使用できます。アプリを終了する必要がある場合は、このソリューションを使用することをお勧めします。
私によると、最善の解決策は、以下のようにアプリのすべてのアクティビティを終了することです。
手順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();
}
同様の問題を解決しました。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;
そして、それはうまくいくようです!:-)