アプリケーションを閉じて、バックグラウンドで実行されないようにしたい。
どうやってするか?これはAndroidプラットフォームでの良い習慣ですか?
「戻る」ボタンを使用すると、アプリは閉じますが、バックグラウンドのままです。バックグラウンドでそれらのアプリを殺すためだけに「TaskKiller」と呼ばれるアプリケーションさえあります。
アプリケーションを閉じて、バックグラウンドで実行されないようにしたい。
どうやってするか?これはAndroidプラットフォームでの良い習慣ですか?
「戻る」ボタンを使用すると、アプリは閉じますが、バックグラウンドのままです。バックグラウンドでそれらのアプリを殺すためだけに「TaskKiller」と呼ばれるアプリケーションさえあります。
回答:
Androidには、ドキュメントに従ってアプリケーションを安全に閉じるメカニズムがあります。終了する最後のアクティビティ(通常、アプリケーションの起動時に最初に表示されるメインのアクティビティ)では、onDestroy()メソッドに数行を配置するだけです。System.runFinalizersOnExit(true)の呼び出しにより、アプリケーションの終了時にすべてのオブジェクトが確実にファイナライズされ、ガベージコレクションが行われます。 必要に応じて、android.os.Process.killProcess(android.os.Process.myPid())を使用してアプリケーションをすばやく強制終了することもできます。これを行う最良の方法は、ヘルパークラスに次のようなメソッドを配置し、アプリを強制終了する必要があるときはいつでもそれを呼び出すことです。たとえば、ルートアクティビティのdestroyメソッドでは(アプリがこのアクティビティを強制終了しないと想定):
また、AndroidはHOMEキーイベントをアプリケーションに通知しないため、HOMEキーが押されたときにアプリケーションを閉じることはできません。Androidは HOMEキーイベントを自分自身に予約するため、開発者はユーザーがアプリケーションを離れることを防止できません。ただしとあなたが判断できHOMEのキーがあることを前提としていヘルパークラスにフラグをtrueに設定することで押されHOMEのキーイベントが表示されていることが発生した場合、その後フラグをfalseに変更し、押されたホームキーは、次に押されていませんでしたアクティビティの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());
}
}
}
killApp()Googleが予測できない動作を引き起こす可能性があることを示しているため、本番アプリケーションはに示すコードを呼び出す必要はありません。
はい!アプリケーションを閉じることができるので、バックグラウンドで実行されなくなります。他のユーザーがコメントしたようにfinish()、Googleが推奨する方法は、プログラムが終了したことを意味するものではありません。
System.exit(0);
そのようにすると、アプリケーションが閉じてバックグラウンドで何も実行されなくなりますが、これは賢く使用して、ファイルを開いたままにしたり、データベースハンドルを開いたままにしたりしないでください。これらは通常、finish()コマンドによってクリーンアップされます。
アプリケーションで[終了]を選択すると、個人的に嫌いですが、実際には終了しません。
これは私がそれをした方法です:
私は置くだけ
Intent intent = new Intent(Main.this, SOMECLASSNAME.class);
Main.this.startActivityForResult(intent, 0);
アクティビティを開くメソッドの内部、次に私が置いたアプリを閉じるように設計されたSOMECLASSNAMEのメソッドの内部:
setResult(0);
finish();
そして、私は私のメインクラスに以下を入れました:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == 0) {
finish();
}
}
しばらくしてから今すぐ自分の質問に答えてください(CommonsWareが最も一般的な答えについてコメントしているため、これを行うべきではないと言っています)。
アプリを終了したいとき:
FLAG_ACTIVITY_CLEAR_TOP(それ以降に開始された他のすべてのアクティビティを終了します。つまり、それらすべてを)開始します。このアクティビティをアクティビティスタックに含めるようにしてください(何らかの理由で事前に終了しないでください)。finish()はこの活動を呼びますこれで十分です。
このコードをボタンのEXITクリックに書き込んでください。
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("LOGOUT", true);
startActivity(intent);
そして、MainActivity.classのonCreate()メソッドで、以下のコードを最初の行として記述します。
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);
}
これがWindows Mobileの動作方法です。これはマイクロソフトが問題について言わなければならないことです:
http://blogs.msdn.com/windowsmobile/archive/2006/10/05/The-Emperor-Has-No-Close.aspx(ブログ投稿のタイトルを2006年からずっと覚えていて悲しいですか?私はグーグルで「皇帝は近づいていない」と検索して記事を見つけました笑)
要するに:
アプリがバックグラウンドで動作しているときにシステムがより多くのメモリを必要とする場合、アプリは閉じられます。ただし、システムがより多くのメモリを必要としない場合、アプリはRAMにとどまり、ユーザーが次に必要になったときにすぐに復帰できるようになります。
O'Reillyでのこの質問の多くのコメントは、Androidはほとんど同じように動作し、Androidが使用しているメモリが必要な場合にのみしばらく使用されていないアプリケーションを閉じることを示唆しています。
これは標準機能であるため、動作を強制的に閉じるように変更すると、ユーザーエクスペリエンスが変わります。多くのユーザーはAndroidアプリを穏やかに却下することに慣れているため、他のタスクを実行した後に戻る意図でアプリを却下すると、アプリケーションの状態がリセットされるか、時間がかかることに不満を感じる場合があります。開く。私は標準的な振る舞いに固執するでしょう。
アクティビティでfinish()メソッドを呼び出すと、その現在のアクティビティに希望する効果が得られます。
上記のすべての答えのどれも私のアプリでうまく機能していません
これが私の作業コードです
終了ボタン:
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
ComponentName cn = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(cn);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
mainIntent.putExtra("close", true);
startActivity(mainIntent);
finish();
そのコードは、他のすべてのアクティビティを閉じて、MainActivityでMainActivityを上に置くことです。
if( getIntent().getBooleanExtra("close", false)){
finish();
}
以下のコードをコピーして、AndroidManifest.xmlファイルを最初のアクティビティタグの下に貼り付けます。
<activity
android:name="com.SplashActivity"
android:clearTaskOnLaunch="true"
android:launchMode="singleTask"
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"
/>
</intent-filter>
</activity>
また、AndroidManifest.xmlファイルのアクティビティタグの下のすべてに以下のコードを追加します
android:finishOnTaskLaunch="true"
Androidデバイスのホーム画面に戻りたいので、次のように使用しました:
moveTaskToBack(true);
public class CloseAppActivity extends AppCompatActivity
{
public static final void closeApp(Activity activity)
{
Intent intent = new Intent(activity, CloseAppActivity.class);
intent.addCategory(Intent.CATEGORY_HOME);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
activity.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
finish();
}
}
そしてマニフェストでは:
<activity
android:name=".presenter.activity.CloseAppActivity"
android:noHistory="true"
android:clearTaskOnLaunch="true"/>
その後、電話をかけることができCloseAppActivity.closeApp(fromActivity)、アプリケーションが閉じられます。
onBackPressedに次のコードを記述するだけです。
@Override
public void onBackPressed() {
// super.onBackPressed();
//Creating an alert dialog to logout
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setMessage("Do you want to Exit?");
alertDialogBuilder.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
}
});
alertDialogBuilder.setNegativeButton("No",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
}
});
//Showing the alert dialog
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
あなたの活動とそれに関連するすべてのサブ活動が終了すると思います。
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();]
if (id == R.id.Exit) {
this.finishAffinity();
return true;
}
return super.onOptionsItemSelected(item);
}