質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

解決済

2回答

2890閲覧

startActivityForResult実行順序について

terater

総合スコア9

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

0クリップ

投稿2019/03/03 12:51

#実現したいこと
Andoroid端末にインストールされている外部アプリケーションを呼び出して、
値を返すようなプログラムを組んでいるのですが値がうまく取れません。
(サンプルコードで、Log.D("BActivity","$array")で値を表示したい)

#サンプルコード(処理イメージを記載しています)

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) var array:ByteArray? = byteArrayOf() // 送信ボタンを定義 val button = findViewById<Button>(R.id.inputButton) // ボタンをクリック時の処理 button.setOnClickListener { fun A(){ val intentA = Intent(Intent.ACTION_SEND) startActivityForResult(intentA, AActivity) } fun B(){ A() val intentB = Intent(Intent.ACTION_SEND) startActivityForResult(intentB, BActivity) C() } fun C(){ val intentC = Intent(Intent.ACTION_SEND) startActivityForResult(intentC, CActivity) } B() } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { // 初期処理 when(requestCode){ AActivity -> { this.array = data?.getByteArrayExtra("number") Log.D("AActivity","1") } BActivity -> { Log.D("BActivity","$array") Log.D("BActivity","2") } CActivity -> { Log.D("CActivity","3") } } } }

#実行結果イメージ
D/CActivity:3
D/null
D/BActivity:2
D/AActivity:1
#質問内容
0. onActivityResultの実行順序についてなのですが、
「setOnClickListener」で呼び出した順番と逆になっています。
イメージ的には呼び出し順番に返ってくると思っていたのですが、
これは最後に呼び出したものから実行されるものなのでしょうか。
それとも呼び出し先のアプリケーションの仕様の問題ですか?
0. 繰り返し実行をすると「Log.D("BActivity","$array")」に値が入っていたりいなかったりするのですが、
実行順序は保証されないものなのでしょうか。その場合、実行順序を決める方法はありますか?
#その他
根本的な処理フローがおかしい場合は、その旨指摘いただけるとありがたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

若干トリッキーな方法になりますが、 kotlinx.coroutines を使えば同期的な順番で処理を記述することができます。

kotlin

1class ActivityResult( 2 val resultCode: Int, 3 val data: Intent? 4) 5 6class MainActivity : AppCompatActivity() { 7 private val results = mutableMapOf<Int, CompletableDeferred<ActivityResult>>() 8 9 override fun onCreate(savedInstanceState: Bundle?) { 10 super.onCreate(savedInstanceState) 11 ... 12 13 button.setOnClickListener { 14 lifecycleScope.launch { 15 val resultA = activityResult(intentA, AActivity).await() 16 Log.d("AActivity", ...) // resultAが返ってきた時点でログ出力 17 18 val resultB = activityResult(intentB, BActivity).await() 19 Log.d("BActivity", ...) // resultBが返ってきた時点でログ出力 20 21 val resultC = activityResult(intentC, CActivity).await() 22 Log.d("CActivity", ...) // resultCが返ってきた時点でログ出力 23 } 24 } 25 } 26 27 private fun activityResult(intent: Intent, requestCode: Int): Deferred<ActivityResult> { 28 val result = CompletableDeferred<ActivityResult>() 29 results[requestCode] = result 30 startActivityForResult(intent, requestCode) 31 return result 32 } 33 34 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { 35 val result = results.remove(requestCode) 36 if (result != null) { 37 result.complete(ActivityResult(resultCode, data)) 38 } else { 39 super.onActivityResult(requestCode, resultCode, data) 40 } 41 } 42}

投稿2019/03/08 08:30

編集2020/02/17 10:57
kakajika

総合スコア3131

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

keicha_hrs

2019/03/08 14:23

なるほど、こういうところでコルーチンの活用の手もあるのですね。勉強になります。
kakajika

2019/03/09 04:48

非同期処理のイメージが強いとは思いますが、単にコールバックが呼ばれるまで待機するというのを実現するのにもcoroutinesが使えますね。 startActivityForResult以外にも、Runtime Permissionsのチェック処理なんかをcoroutines化しておくと一連の処理が色んな所にバラけずに済むのでスッキリします。
terater

2019/04/14 10:44

そのようなライブラリがあるのですね。coroutines別の機会に利用してみようと思います。
guest

0

ベストアンサー

AndroidにおけるActivityの履歴管理は「後入れ先出し」(スタックと呼ばれます)になっていますので、ご提示のコードのsetOnClickListener内でB()というメソッドで3つのActivityを描画したとき、最前面になるのはCActivityというリザルトコードを返すActivityになっているはずです。まずここが期待通りの動作なのでしょうか?

MainActivityに戻ったときに実行されるonActivityResult()では、終了したActivityの順番通りに結果を受け取りますから、最初に終了するActivity=最前面にあるActivity=CActivityの結果を最初に受け取ることになるでしょう。この流れから考えれば、質問に記された結果になっているのは必然ではないかと思います。

投稿2019/03/04 14:40

keicha_hrs

総合スコア6768

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

terater

2019/03/06 12:27

現状の動作は理解いたしました。 >>まずここが期待通りの動作なのでしょうか? 期待通りではありません。 ①「AActivity」開始→「AActivity」終了 ②「BActivity」開始→「BActivity」終了 と順番に処理をしたいです。 (①の戻り値を②で使用をしたいため。) https://developer.android.com/guide/components/tasks-and-back-stack?hl=ja スタックの順番を変える方法はないと見えるのですか、 例えばAActivity開始後すぐに結果を返してもらうように、 呼び出し側から制御出来ないでしょうか?
keicha_hrs

2019/03/06 23:26 編集

外部アプリケーションの構造がわからないので確実なことは言えませんが、自作プログラムで外部アプリケーションを呼び出すときに、C→B→Aの順で呼び出すように書き換える(連続して呼び出したときにAが最前面に来るように最後に呼び出す)方法は採れないのでしょうか? 或いは、setOnClickListenerではAのみを呼び出し、MainActivityのonActivityResultで結果を受け取ってから、そこで初めてBを呼び出す流れにすることはできないのでしょうか?
terater

2019/04/14 10:41

API仕様書では前者の方法でなかったので、後者の方法でコーディングして何とか動きました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問