私のプログラムは、特定のアプリケーションを強制終了する必要があります。ルート化されていない在庫のデバイスで可能ですか? はいの場合 - どのように?そのプロセス名と PID はわかっています。
2 に答える
もう一度答えるのが遅すぎますが、今日同じ状況で走っていたので、誰かを助けるために自分の発見を共有しようと思いました。
まず第一に、あなたは何を殺すことができ、何を殺すことができないかを理解する必要があります。Androidの観点からは、アプリケーションは他のOSとは異なります。Androidアプリケーションは、パッケージにパックされた多くのコンポーネント(アクティビティ、ブロードキャストレシーバー、サービス、最も重要なタスクなど)で構成されています。パッケージは、実行中のコンポーネントに応じて、複数のプロセスを実行することができます。
ここで興味深いのは、プロセスの一部またはすべてが強制終了された場合、Androidパッケージが(androidによって)強制終了または停止されたとは見なされないことです。実際、パッケージは、プロセスがまったく実行されていなくても実行できます。この効果は、エミュレーターを起動し、プログラム(ブラウザーなど)を起動してから、を介してそのプロセスを強制終了すると確認できます。その後、アプリケーションのパッケージ設定に移動すると、[強制停止]ボタンが有効になっていることがわかります。これは、アプリケーションがまだ稼働していることを意味します。実行中(Androidの観点から)。ここで起こったことは、アプリケーションに1つ以上のタスクが凍結されていることですDDMS
(Settings --> Applications --> Manage Applications --> All --> Browser)
。つまり、Androidはアプリケーションのアクティビティ(1つまたは複数のタスク)の状態を保存しているため、ユーザーがパッケージに戻った場合、パッケージはまだ実行されているか、それよりも優れています。これで、[強制停止]ボタンをクリックすると、Androidはこれらの凍結されたタスクをすべて破棄し、ユーザーがアプリケーションに戻ると、最初のアクティビティが表示されます。タスクfroyo
は、ユーザー( [強制停止]ボタンから)のみを強制終了できないものです。システムまたはシステムの同じキーで署名されたサードパーティのアプリケーションがそれを実行できます(おそらくルート対応のアプリケーションですが、私はこれは確認されていません)。一方、プロセスいくつかの制限に従う限り、使用するメモリを強制終了して再利用できるものです。
- あなたには
android.permission.KILL_BACKGROUND_PROCESSES
許可があります。- プロセスはシステムまたはルートプロセスではありません。
- プロセスは、永続的なコンポーネントに属していません。
- このプロセスは、システムが他の手段で動作するために重要ではありません。
あなたがそれらについて何もする必要がない一番のルールに加えて、Androidはこれを処理します。
ActivityManager
パッケージが持つすべてのプロセスを一度に強制終了するために使用できる便利な機能があります。これを呼び出すと、Androidは、強制終了できるすべてのプロセスを強制終了し、メモリを解放します。ただし、このパッケージのタスクの状態は保存され、ユーザーがアプリケーションに戻ると、システム自体がタスクを強制終了しない限り、最後に実行していたことが表示されます。これは、リソースが必要であるか、状態がかなり前(約30分)に保存されたために発生する可能性があります。副作用は、ユーザーがすべてのアプリケーションがデスクトップオペレーティングシステムのようであると考えているため、アプリケーションが実際に閉じているとは思わないことですが、これはAndroidの生活です。
今度はコードに:
私のプロジェクトでは、これを実現するために3つの関数を用意しました。
最初のものは、パッケージが持つ可能性のある最初のプロセスpidを探し、存在しない場合は-1を返します。
private Context cx;
private ActivityManager am = (ActivityManager) cx.getSystemService(Context.ACTIVITY_SERVICE);
public int findPIDbyPackageName(String packagename) {
int result = -1;
if (am != null) {
for (RunningAppProcessInfo pi : am.getRunningAppProcesses()){
if (pi.processName.equalsIgnoreCase(packagename)) {
result = pi.pid;
}
if (result != -1) break;
}
} else {
result = -1;
}
return result;
}
2つ目は愚かなことをしますが、私のプロジェクトにはそれが必要です。
public boolean isPackageRunning(String packagename) {
return findPIDbyPackageName(packagename) != -1;
}
3番目は仕事をします。
public boolean killPackageProcesses(String packagename) {
boolean result = false;
if (am != null) {
am.killBackgroundProcesses(packagename);
result = !isPackageRunning(packagename);
} else {
result = false;
}
return result;
}
これらは、エミュレーターAPI 8および9と、API 15を備えた実際のデバイス(Galaxy S2)で動作することが確認されており、不要な限り、アプリケーションのプロセス(自分のプロセスだけでなく)を強制終了します。
android.os.Process.killProcess
次に、次のように記載されているドキュメントについて説明します。
...通常、これは、呼び出し元のパッケージ/アプリケーションを実行しているプロセスと、そのアプリによって作成された追加のプロセスのみを意味します。..。
「呼び出し元のパッケージ/アプリケーションを実行するプロセス」とは、独自のアプリケーションではなく、ホームランチャーアプリケーションを意味すると思います。アプリケーションは呼び出し元であり、呼び出し元のパッケージ/アプリケーションを実行するプロセスは、ホームランチャーまたはアプリケーションを起動した他のアプリです。killBackgroundProcesses
これは、関数とandroid.os.Process.killProcess
関数が実際にサードパーティのアプリケーションで機能していることを説明する唯一の方法です。
ドキュメントに立って:
指定された PID でプロセスを強制終了します。この API を使用すると、PID に基づいて任意のプロセスを強制終了するように要求できますが、カーネルは、実際に強制終了できる PID に標準的な制限を課すことに注意してください。通常、これは、呼び出し元のパッケージ/アプリケーションを実行しているプロセスと、そのアプリによって作成された追加のプロセスのみを意味します。共通の UID を共有するパッケージは、互いのプロセスを強制終了することもできます。
自分のプロセスを殺すことができます..
プロセスのドキュメントを参照してください。実行しようとしましたadb shell kill pid
が、スーパーユーザーの許可が必要です