branch10480’s blog

Topics that I've learned.

アクティビティ間の移動

画面遷移するときにはアクティビティ間の移動が発生する。今回はアクティビティの移動についてまとめる。

アクティビティを別のアクティビティから開始する

別のアクティビティを開始する方法は2通りあるが、両方とも Intent オブジェクトを渡す。

  • startActivity()
  • startActivityForResult()

Intent では以下2通りの指定ができる。

  1. 明示的に呼び出す先のアクティビティを正確に指定する
  2. 実行する操作タイプを記述して暗黙的な起動にすることができる

2の場合は、別のアプリが起動することがある。

startActivity()

新しく起動するアクティビティから結果を受け取る必要がない場合に使用する。

val intent = Intent(this, SignInActivity::class.java)
startActivity(intent)

ユーザーがメール送信できるようにする Intent の作り方はこちら。

val intent = Intent(Intent.ACTION_SEND).apply {
    putExtra(Intent.EXTRA_EMAIL, recipientArray)
}
startActivity(intent)

EXTRA_EMAIL のエクストラはメールの送信先を表す。メールアプリはこの Intent を受け取り、宛先フィールドに配置する。そして、メール送信操作が完了(アクティビティが終了)すると元のアクティビティが再開されるという動き方をする。

startActivityResult()

アクティビティが終了する時に、結果を受け取る必要がある場合に使用する。

e.g. 性別を選ばせる選択画面を表示してユーザーが選択を完了した場合、その選択された性別を受け取る

この場合は startActivityForResult(Intent, int) メソッドを使う。このメソッドの場合は整数が引数として渡ってくる。

int 部分はIDとして扱われ、複数の startActivityForResult(Intent, int) の識別に使用できる。

結果は onActivityResult(int, int, Intent) で受け取る。

class MyActivity : Activity() {
    // ...

    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
            // When the user center presses, let them pick a contact.
            startActivityForResult(
                    Intent(Intent.ACTION_PICK,Uri.parse("content://contacts")),
                    PICK_CONTACT_REQUEST)
            return true
        }
        return false
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
        when (requestCode) {
            PICK_CONTACT_REQUEST ->
                if (resultCode == RESULT_OK) {
                    startActivity(Intent(Intent.ACTION_VIEW, intent?.data))
                }
        }
    }

    companion object {
        internal val PICK_CONTACT_REQUEST = 0
    }
}

子アクティビティが終了すると、 setResult(int) を呼び出して親にデータを返すことができる。その際、子アクティビティには必ず結果コードを渡す必要がある

結果コードには標準の結果コードである

  • RESULT_CANCELED
  • RESULT_OK

または、RESULT_FIRST_USER から始まる カスタム値を使用できる。

加えて、子アクティビティは任意で Intent オブジェクトを渡すこともできる。

クラッシュなどで子アクティビティが失敗すると、 RESULT_CANCELED を親アクティビティは受け取る。

アクティビティの連携

アクティビティを新しく起動する場合はライフサイクルコールバックの順番に気をつけること!

起動する場合、2つのアクティビティが同じプロセス(アプリ)上に存在するときのみ順番が保証される。この場合、以下の順序で実行される。

  1. アクティビティAの onPause() が実行される
  2. アクティビティBの onCreate() onStart() onResume() の各メソッドが順次実行される。(このとき、アクティビティBにユーザー視点のフォーカスがある)
  3. アクティビティAが表示されなくなった場合、onStop() が実行される。