am force-stop
端末を変えるあるアプリのプロセスとサービスをすべて終了させます。
- コマンド
- adb shell am force-stop
- コマンド
- アクティビティと intent(am)
- リスク
- 端末を変える
構文
am force-stop <package>使用例
am force-stop com.exampleアンインストールも消去もせずに、暴れているアプリを止めます。
top -b -n 1 -m 10何を止める前に、実際に CPU を食っているものを確認します。
出力の読み方
通常は何も出ません。無言を成功とみなし、`Error:` や例外、権限の行があれば失敗と考えます。確証が欲しければ、出力の不在を信じるのではなく、後で `top` にそのアプリのプロセスがないかを見てください。
出力フィールド
| フィールド | 意味 |
|---|---|
| (no output) | コマンドが実行されました。 |
| Error: … | パッケージを解決できなかった、または呼び出しが拒否されました。 |
必要な権限
root も `adb root` も `su` も不要で、認可済みの `adb` 接続がすべてです。`am force-stop` は `ActivityManagerService.forceStopPackage` に届き、そこで呼び出し元の `android.Manifest.permission.FORCE_STOP_PACKAGES` が確認され、無ければ例外になります。Shell パッケージは自分のマニフェスト(`packages/Shell/AndroidManifest.xml`)でまさにその権限を宣言していて、だからこのコマンドはケーブルからだけ通り、他のほぼどこからも通りません。既定の効果範囲が思っているより広いのも、同じマニフェストのせいです。そこには `INTERACT_ACROSS_USERS_FULL` も入っていて、`runForceStop` はユーザー id を `UserHandle.USER_ALL` に設定して始まり、`--user` を渡したときだけ絞ります。つまり引数 1 つの素朴な形は、画面を見ている人のアプリを止めるのではなく、端末上のすべての Android ユーザーで同時に止めます。仕事用プロファイルも、セカンダリユーザーも、同じアプリのクローンもです。目の前のユーザーだけのつもりなら、明示してください。他に間に立つものはありません。確認も、ドライランも、取り消せるパッケージ単位の許可もなく、システムアプリの force-stop も止められません。user ビルドでは `adb root` はどのみち拒否されますし、shell が既に必要な権限を持っている以上、通ったところで何の足しにもなりません。
エラーメッセージの読み解き
| メッセージ | 意味 |
|---|---|
| Error: Unknown option: --user0 | `runForceStop` が受け付けるオプションは `--user` ただ 1 つです。それ以外は標準エラーにそのまま出て、`forceStopPackage` を呼ぶ **前に** -1 を返します。つまり `--user0` のようにくっつけた書き方、`-u` という略記、紛れ込んだ `--all` は、アプリを動かしたままにしておきながら、拒否ではなく警告のような顔で表示されます。行の口調ではなく終了コードを見てください。 |
| Exception occurred while executing 'force-stop': | `Throwable` が `onCommand` から抜け、標準エラーに空行とこのバナーとトレースが出ます。`java.lang.IllegalArgumentException: Argument expected after "force-stop"` は、パッケージ名を渡していないという意味です。`android.permission.FORCE_STOP_PACKAGES` を名指しする `java.lang.SecurityException` は呼び出しが shell でも root でもなかったという意味で、ケーブル越しでは普通、`run-as` の中にいて uid 2000 でなくなっているということです。 |
| Unknown command: force stop | ハイフンはサブコマンド名の一部です。引用したり分けたりすると `am` には `force` だけが見え、`handleDefaultCommands` がこれを **標準出力** に出して、どのプロセスにも触れずに -1 を返します。成功した force-stop の無言とは似ても似つかないので、そこだけは救いです。 |
| cmd: Can't find service: activity | `am` は `cmd activity` のラッパーで、その `cmd` がサービスマネージャに `activity` を見つけられませんでした。何も止まっていません。`system_server` が `activity` を公開する前の起動途中なら想定内で、パッケージ名が間違っている合図ではありません。 |
何が変わるか、そして戻る道
何も削除されず、次に起動されるかブロードキャストで起こされれば、アプリはまた動き出します。ただしプロセス内の未保存の状態は失われ、そのアプリが予約していたアラームやジョブは、再び動くまで取り消されます。元に戻すコマンドはありません。直し方はアプリを開くことです。
バージョンとメーカーに関する注意
- CPU 順に並んだプロセス表からの force-stop は押し間違いが起きやすく、放っておくつもりだったアプリが未保存の状態を失います。
- 無効化とは違います。アプリはいつでも再び動き出せます。
これには UI があります
Android System Monitor はこのコマンドを USB 経由で実行し、返ってきたものを解析します。Chromium 系ブラウザだけで、SDK も不要、どこにもアップロードしません。
関連コマンド
am force-stop と同じ作業で出てくるコマンド。
| コマンド | 何をするか |
|---|---|
| top | 1 回分のプロセス表:CPU 使用率、メモリ、状態、コマンドライン。 |
| dumpsys meminfo | どのプロセスがメモリを最も使っているかを、PSS(比例配分したサイズ)で表示します。 |
| am start | コンポーネント指定または intent 指定でアクティビティを起動します。ディープリンクの解決を確かめる最短経路です。 |
他のアクティビティと intent(am)コマンド
| コマンド | 何をするか |
|---|---|
| am broadcast | ブロードキャスト intent を送ります。SystemUI の demo mode などプラットフォームのレシーバをシェルから動かす方法です。 |
Web ADB ツール群のパーサを書きながら、AOSP・toybox・カーネルのソースに突き合わせて確認しています。バージョンやメーカーで本当に挙動が変わるところは、世界の半分の端末で間違いになる数値を出す代わりに、そう書いてあります。