Android の finish() / finishAndRemoveTask() / moveTaskToBack() の違い

Android で「アプリを終了したい」と調べると、finish()finishAndRemoveTask()moveTaskToBack(true) が候補に出てきます。名前だけ見ると似ていますが、やっていることは違います。

この記事では、最小 Activity で実際にログを取り、3つの違いを整理します。

先に比較表

API何をするか実測したライフサイクルプロセス
finish()今の Activity を閉じるonPauseonStoponDestroy残った
finishAndRemoveTask()Activity を閉じ、タスクを最近使ったアプリ一覧から外すonPauseonStoponDestroy残った
moveTaskToBack(true)タスクを背面へ送るonPauseonStop残った

確認環境:

Android Emulator Medium_Phone_API_36.0
Android 16 / API 36
targetSdkVersion 36
確認日 2026-07-14

finish(): 今の Activity を閉じる

finish() は、現在の Activity を終了します。

finish()

実測ログ:

I/ExitProbe: onCreate pid=11507
I/ExitProbe: onStart pid=11507
I/ExitProbe: onResume pid=11507
I/ExitProbe: runMode finish pid=11507
I/ExitProbe: onPause pid=11507
I/ExitProbe: onStop pid=11507
I/ExitProbe: onDestroy pid=11507
pid_after_18s=11507

Activity は onDestroy まで進みましたが、プロセスは残りました。finish() はアプリプロセスを殺すAPIではありません。

画面を閉じたいだけなら、基本はこれで十分です。

finishAndRemoveTask(): タスクも最近使ったアプリから外す

finishAndRemoveTask() は、Activity を終了し、その Activity が属するタスクを最近使ったアプリ一覧から外します。

finishAndRemoveTask()

実測ログ:

I/ExitProbe: onCreate pid=11548
I/ExitProbe: onStart pid=11548
I/ExitProbe: onResume pid=11548
I/ExitProbe: runMode finish_remove pid=11548
I/ExitProbe: onPause pid=11548
I/ExitProbe: onStop pid=11548
I/ExitProbe: onDestroy pid=11548
pid_after_18s=11548

Activity のライフサイクルだけ見ると、finish() とかなり似ています。違いはタスクの扱いです。

ログアウト完了後や、ワンショットの認証フローなど、「このタスクを最近使ったアプリに残したくない」理由があるときに検討します。普通の戻る操作の代わりに毎回使うAPIではありません。

moveTaskToBack(true): 終了ではなく背面送り

moveTaskToBack(true) は、タスクを背面へ送ります。ホームボタンを押したときに近い挙動です。

moveTaskToBack(true)

実測ログ:

I/ExitProbe: onCreate pid=11587
I/ExitProbe: onStart pid=11587
I/ExitProbe: onResume pid=11587
I/ExitProbe: runMode move_task_back pid=11587
I/ExitProbe: onPause pid=11587
I/ExitProbe: onStop pid=11587
pid_after_18s=11587

onDestroy は呼ばれませんでした。Activity は停止状態になり、タスクが背面に回っただけです。

「終了ボタン」でこれを呼ぶと、ユーザーからはアプリが閉じたように見えます。ただし、実際には終了ではありません。あとで最近使ったアプリから戻れば、同じタスクに戻ります。

System.exit() とは別物

この3つはどれも、System.exit() の代わりにプロセスを殺すAPIではありません。

System.exit(0) を同じ最小アプリで試すと、Activity の onPause / onStop / onDestroy は出ず、システム側に次のようなログが出ました。

I/ExitProbe: runMode system_exit pid=11636
I/ActivityManager: Process net.ecoop.exitprobe (pid 11636) has died: fg  TOP
W/ActivityTaskManager: Force removing ActivityRecord{...}: app died, no saved state
pid_after_18s=

終了方法の比較は Android で System.exit() を使ってはいけない理由と、終了方法のまとめ にもまとめています。

どれを選ぶか

迷ったら、まずはこの順で考えるとよいです。

  1. 画面を閉じたいだけなら finish()
  2. タスクを最近使ったアプリからも消したい明確な理由があるなら finishAndRemoveTask()
  3. ホームへ戻したように背面へ送りたいだけなら moveTaskToBack(true)
  4. System.exit()Process.killProcess() は通常の終了処理には使わない

名前が似ていても、Activity、タスク、プロセスは別物です。終了処理を書くときは、どのレイヤーを変えたいのかを分けると判断しやすくなります。

ImageMagick の xmp:validate とは何か。XMP検証エラーを回避する方法

ImageMagick で JPEG や PNG を処理していると、次のような警告に出会うことがあります。

identify: CorruptImageProfile `bad.jpg' (XMP) @ warning/profile.c/ValidateXMPProfile/2011.

これは画像に埋め込まれた XMP メタデータを ImageMagick が XML として読もうとして、壊れていると判断したときの警告です。画像のピクセル変換そのものが失敗しているとは限りません。

この記事では、壊れた XMP 入りの JPEG を手元で作って、xmp:validate を付けたときに何が起きるかを確認します。

xmp:validate は何をしているのか

xmp:validate は ImageMagick の -define で指定する設定です。

公式の defines ページでは、xmp:validate={true,false} は「画像に埋め込まれた XMP プロファイルを検証する」と説明されています。

XMP は、ざっくり言うと画像に入る XML 形式のメタデータです。撮影・編集ソフト・権利情報・説明文などが入ることがあります。ImageMagick 側では、XML delegate が有効なビルドだと、この XMP を XML として読めるか確認できます。

手元の ImageMagick 7.1.2-27 では、xmp:validate=true を明示したときに CorruptImageProfile ... (XMP) の警告を確認しました。公式説明には「デフォルトで検証」とありますが、少なくともこの環境では、素の identify や変換では警告が出ませんでした。バージョンやビルド設定で挙動が違う可能性があるので、まず自分の環境で確認するのがよいです。

確認環境は以下です。

Version: ImageMagick 7.1.2-27 Q16-HDRI aarch64 e4c2b403b:20260705 https://imagemagick.org
Features: Cipher DPC HDRI Modules
Delegates (built-in): bzlib freetype heic jng jpeg lcms ltdl lzma png tiff webp xml zlib zstd

壊れた XMP 入り JPEG を作る

まず、わざと XML として壊れた XMP ファイルを作ります。

printf '\xff\xfe\x00\x00not xml\n' > bad.xmp
magick -size 32x32 xc:white base.jpg

普通に -profile bad.xmp すると環境によっては追加時点で警告されるので、ここでは xmp:validate=false を付けて、壊れた XMP を持つ JPEG を作ります。

magick base.jpg -define xmp:validate=false -profile bad.xmp bad.jpg

XMP プロファイルが入っていることは identify -verbose で確認できます。

magick identify -verbose bad.jpg 2>/dev/null | grep -Ei 'profiles|profile-xmp'

出力:

  Profiles:
    Profile-xmp: 12 bytes

xmp:validate=true で警告を再現する

xmp:validate=true を付けて identify します。

magick identify -define xmp:validate=true bad.jpg
echo $?

手元ではこうなりました。

bad.jpg JPEG 32x32 32x32+0+0 8-bit Grayscale Gray 256c 210B 0.000u 0:00.001
identify: CorruptImageProfile `bad.jpg' (XMP) @ warning/profile.c/ValidateXMPProfile/2011.
0

ここで大事なのは、終了コードが 0 のままだったことです。つまり、少なくともこのケースでは「警告は出るが、コマンドとしては成功」です。スクリプトが stderr の文字列を見て失敗扱いしている場合は別ですが、終了コードだけを見る処理なら失敗にはなりません。

警告だけ消すなら -quiet

ログに警告を出したくないだけなら、-quiet で警告は消えました。

magick identify -quiet -define xmp:validate=true bad.jpg
echo $?

出力:

bad.jpg JPEG 32x32 32x32+0+0 8-bit Grayscale Gray 256c 210B 0.000u 0:00.001
0

ただし、これは警告を黙らせるだけです。壊れた XMP は画像内に残ります。

検証を止めるなら xmp:validate=false

XMP の検証自体を止めるなら、入力ファイルより前に -define xmp:validate=false を置きます。

magick identify -define xmp:validate=false bad.jpg
echo $?

出力:

bad.jpg JPEG 32x32 32x32+0+0 8-bit Grayscale Gray 256c 210B 0.000u 0:00.000
0

変換でも同じ考え方です。

magick -define xmp:validate=false bad.jpg out.png

-define は入力を読む前に効かせたいので、迷ったら入力ファイル名より前に置くのが安全です。

XMP を消すなら +profile xmp

壊れた XMP が不要なら、検証を止めて読み込み、そのあとで XMP プロファイルだけ削除します。

magick -define xmp:validate=false bad.jpg +profile xmp clean-no-xmp.jpg
echo $?

出力:

0

削除後のファイルを確認します。

magick identify -verbose clean-no-xmp.jpg 2>/dev/null | grep -Ei 'profiles|profile-xmp'

出力は空でした。さらに、削除後のファイルは xmp:validate=true で読んでも警告が出ません。

magick identify -define xmp:validate=true clean-no-xmp.jpg
echo $?

出力:

clean-no-xmp.jpg JPEG 32x32 32x32+0+0 8-bit Grayscale Gray 256c 165B 0.000u 0:00.000
0

すべてのメタデータを消してよいなら -strip

XMP だけでなく、EXIF や ICC などのプロファイル、コメント類も落としてよいなら -strip が使えます。

magick -define xmp:validate=false bad.jpg -strip clean-strip.jpg
echo $?

出力:

0

-strip は画像を軽くしたいときには便利ですが、色管理の ICC プロファイルや撮影情報も落ちます。Web用サムネイルなら問題ないことが多い一方、印刷・写真管理・権利情報を残したい用途では雑に使わない方がよいです。

どれを使うべきか

目的別に分けると、こうです。

目的コマンド例注意
警告をログに出したくないだけmagick identify -quiet -define xmp:validate=true bad.jpgXMP は残る
XMP 検証をスキップしたいmagick -define xmp:validate=false input.jpg output.png壊れた XMP を温存する場合がある
XMP だけ消したいmagick -define xmp:validate=false input.jpg +profile xmp output.jpgXMP 内の説明・権利情報も消える
全メタデータを消してよいmagick -define xmp:validate=false input.jpg -strip output.jpgEXIF/ICC/コメントも消える

Webアプリの画像変換で「ユーザー投稿画像を縮小して表示するだけ」なら、-define xmp:validate=false-strip の組み合わせで済むことが多いです。逆に、写真のメタデータや色プロファイルを大事にする処理では、-strip ではなく +profile xmp のように削除対象を絞った方が安全です。

さいごに

xmp:validate は、画像のピクセルではなく XMP メタデータの検証に関わる設定です。CorruptImageProfile ... (XMP) が出ても、まずは終了コード、出力ファイル、XMP が必要かどうかを分けて見た方がよいです。

今回の手元検証では、警告が出ても終了コードは 0-quiet は警告を隠すだけ、xmp:validate=false は検証を止める、+profile xmp-strip はメタデータを実際に削除する、という違いが確認できました。

関連:

ECOOPとは? ヨーロッパ最古のオブジェクト指向プログラミング国際会議

ECOOP(European Conference on Object-Oriented Programming)は、1987年から毎年ヨーロッパで開かれているプログラミング言語分野の国際会議です。名前のとおりオブジェクト指向プログラミングの会議として始まり、現在はプログラミング言語全般を扱う、ヨーロッパで最も歴史の長い年次会議になっています。

先にお断りしておくと、当サイト(ecoop.net)はこの会議とは無関係の個人サイトです。「ecoop」で検索してここへ着いた方の多くは会議を探していると思うので、この記事で会議の概要と、公式情報・論文の入手先をまとめておきます。

会議の概要

続きを読む ECOOPとは? ヨーロッパ最古のオブジェクト指向プログラミング国際会議

Makefile変数チートシート:自動変数 $@ $< $^ と := = の違い

Makefileを書いていると、$@$< みたいな記号や、=:= の使い分けで手が止まりがちです。この記事は変数まわりだけを逆引きでまとめたチートシートです。挙動はすべて手元の GNU Make で実行して確認しています。

もっと踏み込んだ仕様は GNU Make 4.4 日本語マニュアル 第6章「変数の使い方」 を参照してください。この記事はその逆引き版です。

=:= の違い(ここだけは押さえる)

続きを読む Makefile変数チートシート:自動変数 $@ $< $^ と := = の違い

Makefileの条件分岐 ifeq / ifdef 完全ガイド

Makefile で「デバッグビルドのときだけフラグを足したい」「OS ごとにコマンドを変えたい」といった分岐をしたいとき使うのが ifeqifdef です。書き方に少しクセがあるので、実例つきでまとめました。挙動はすべて手元の GNU Make で実行して確認しています。

仕様の詳細は GNU Make 4.4 日本語マニュアル 第7章「Makefileの条件分岐」 を参照してください。この記事はその実例版です。

4つの条件ディレクティブ

続きを読む Makefileの条件分岐 ifeq / ifdef 完全ガイド

rsync でファイル名が文字化けするときの対処(–iconv と macOS の NFD 問題)

Mac から Linux サーバへ rsync でファイルを送ったら、日本語ファイル名の濁点・半濁点が分離して「テ゛ータ」のようになった。検索やタブ補完でファイル名がヒットしない。同期し直すたびに全ファイルが再転送される。こうした症状は、文字コードそのものではなく Unicode の正規化形式(NFC/NFD)の違いが原因です。

続きを読む rsync でファイル名が文字化けするときの対処(–iconv と macOS の NFD 問題)

rsync の終了コード一覧と意味

cron で回している rsync が 0 以外の終了コードを返してきたとき、その番号が何を意味するのかを調べるためのリファレンスです。まず一覧を載せて、そのあとで実際によく遭遇するコードの読み方とスクリプトでの扱い方を説明します。

終了コードは直後に echo $? で確認できます。

$ rsync -a /path/to/src/ /path/to/dst/
$ echo $?
0

終了コード一覧(rsync 3.4.4 の man ページより)

続きを読む rsync の終了コード一覧と意味

WindowsでUDP通信・ポート確認をする方法(PowerShell/ncat)

「WindowsでUDP通信を試したいのに、telnetもTest-NetConnectionも使えない」。結論から言うと、Windows標準のtelnetクライアントもTest-NetConnectionもTCP専用で、UDPには使えません。UDPを送受信するには、PowerShellのUdpClientか、ncat(Nmapに含まれるnetcat互換ツール)を使います。

※動作環境について:このページのコマンドは Windows 11(build 26200)+ Windows PowerShell 5.1 で動作を確認しています(2026-07-09)。Windows 10 や PowerShell 7 でも、使っているのは共通の .NET(UdpClient)と NetTCPIP モジュール(Get-NetUDPEndpoint など)なので同じように動くはずですが、表示のこまかな差は環境によって出ることがあります。

結論:WindowsでUDPを試す方法

続きを読む WindowsでUDP通信・ポート確認をする方法(PowerShell/ncat)

UDPポートが開いているか確認する方法と、なぜ難しいのか

結論から言うと、UDPのポートが開いているかどうかは100%確実には確認できません。TCPのポート確認とは前提がまったく違うからです。それでも実用上「開いていそう」「閉じていそう」を判断する手段はいくつかあります。この記事では、まず何が難しいのかを説明したあと、確認手段を確実性の高い順に紹介します。

  • 一番確実:相手が応答を返すプロトコルなら、実際に問い合わせて応答を見る
  • 次に現実的:nmap -sU でスキャンする(要root)
  • 自分のサーバなら:待ち受けているプロセスをサーバ側で直接確認する
  • 補助:tcpdump でパケットが実際に届いたか見る

nc -vzu だけで判定するのはおすすめしません。理由は次の章で実際に確認します。

なぜUDPのポート確認はTCPより難しいのか

続きを読む UDPポートが開いているか確認する方法と、なぜ難しいのか

netcat(nc)でUDP通信する使い方まとめ(-u オプションとBSD/GNU/RHEL系統別)

nc(netcat)でUDP通信するには -u オプションを付けるだけです。ただし nc には実装がいくつかあり、特に待ち受け(-l)のオプションの書き方が系統によって違います。ここを取り違えるとコマンドがエラーになったり、意図と違う動きをします。この記事では基本の使い方と、系統ごとの違いを実際に動かして確認した結果でまとめます。

基本:ncでUDPを送受信する

以降の基本操作は、macOS標準のnc(BSD系、OpenBSD nc由来)で実機確認したコマンドです。-u での基本的な送受信はどの系統でも同じですが、待ち受け(-l)まわりのオプションは系統ごとに変わります。詳しくは次の章にまとめました。

続きを読む netcat(nc)でUDP通信する使い方まとめ(-u オプションとBSD/GNU/RHEL系統別)