Bagaimana cara mengembalikan hasil (startActivityForResult) dari Aktivitas TabHost?

275

Saya memiliki 3 kelas dalam contoh saya: Kelas A, kegiatan utama. Kelas A memanggil startActivityForResult:

Intent intent = new Intent(this, ClassB.class);
startActivityForResult(intent, "STRING");

Kelas B, kelas ini adalah TabActivity:

Intent intent = new Intent(this, ClassC.class);
tabHost.addTab...

Kelas C, kelas ini adalah Kegiatan reguler:

Intent intent = this.getIntent();
intent.putExtra("SOMETHING", "EXTRAS");
this.setResult(RESULT_OK, intent);
finish();

onActivityResult dipanggil di Kelas A, tetapi resultCode RESULT_CANCELEDbukan RESULT_OKdan maksud yang dikembalikan adalah nol. Bagaimana cara mengembalikan sesuatu dari Aktivitas di dalam TabHost?

Saya menyadari bahwa masalahnya adalah bahwa Kelas C saya benar-benar berjalan di dalam Kelas B, dan Kelas B adalah apa yang mengembalikan RESULT_CANCELEDkembali ke Kelas A. Saya hanya belum tahu pekerjaan di sekitar.

Cameron McBride
sumber

Jawaban:

366

Ya Tuhan! Setelah menghabiskan beberapa jam dan mengunduh sumber Android, saya akhirnya menemukan solusi.

Jika Anda melihat kelas Activity, Anda akan melihat, finish()metode itu hanya mengirim kembali hasilnya jika ada mParentproperti yang disetel ke null. Kalau tidak hasilnya hilang.

public void finish() {
    if (mParent == null) {
        int resultCode;
        Intent resultData;
        synchronized (this) {
            resultCode = mResultCode;
            resultData = mResultData;
        }
        if (Config.LOGV) Log.v(TAG, "Finishing self: token=" + mToken);
        try {
            if (ActivityManagerNative.getDefault()
                .finishActivity(mToken, resultCode, resultData)) {
                mFinished = true;
            }
        } catch (RemoteException e) {
            // Empty
        }
    } else {
        mParent.finishFromChild(this);
    }
}

Jadi solusi saya adalah mengatur hasil ke aktivitas induk jika ada, seperti itu:

Intent data = new Intent();
 [...]
if (getParent() == null) {
    setResult(Activity.RESULT_OK, data);
} else {
    getParent().setResult(Activity.RESULT_OK, data);
}
finish();

Saya harap itu akan membantu jika seseorang mencari masalah ini lagi.

Ilya Taranov
sumber
1
Saya memposting solusi hacky di sini, sederhana dan melibatkan aktivitas transparan tanpa konten - itu mendapatkan fungsi siklus hidup normal dan membuat semuanya lebih mudah. stackoverflow.com/questions/7812120/…
CQM
Itu luar biasa! Terima kasih terima kasih terima kasih! Ini bekerja dengan sempurna dan dengan sedikit keributan. Saya telah mengganti metode setResult () reguler untuk semua Aktivitas saya dengan permata kecil ini. Terima kasih!
Scott Biggs
Saya menggunakan solusi Anda, masih kode saya tidak menangkap metode onactivityresult ketika kembali. tolong bantu saya .. apakah saya perlu menggunakan hal lain?
skygeek
11
Mengapa mengembalikan hasil dalam suatu Kegiatan yang tidak didokumentasikan di manapun dalam panduan API, menurut saya aneh.
alex.p
Sial! Kerja bagus, Illya! Terima kasih
Sirelon
64

http://tylenoly.wordpress.com/2010/10/27/how-to-finish-activity-with-results/

Dengan sedikit modifikasi untuk "param_result"

/* Start Activity */
public void onClick(View v) {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setClassName("com.thinoo.ActivityTest", "com.thinoo.ActivityTest.NewActivity");
    startActivityForResult(intent,90);
}
/* Called when the second activity's finished */
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch(requestCode) {
    case 90:
        if (resultCode == RESULT_OK) {
            Bundle res = data.getExtras();
            String result = res.getString("param_result");
            Log.d("FIRST", "result:"+result);
        }
        break;
    }
}

private void finishWithResult()
{
    Bundle conData = new Bundle();
    conData.putString("param_result", "Thanks Thanks");
    Intent intent = new Intent();
    intent.putExtras(conData);
    setResult(RESULT_OK, intent);
    finish();
}
Dave S
sumber
2
Sederhana, setResultadalah hal utama. Tetapkan untuk sesuatu, atau nilai misalnya RESULT_OKdan Anda baik untuk pergi; setResult(RESULT_OK);. Bantu saya, +1
Afzaal Ahmad Zeeshan
16

Intent.FLAG_ACTIVITY_FORWARD_RESULT?

Jika diatur dan maksud ini digunakan untuk meluncurkan aktivitas baru dari yang sudah ada, maka target balasan dari aktivitas yang ada akan ditransfer ke aktivitas baru.

hanya pemikiran
sumber
1

Anda bisa mengimplementasikan onActivityResult di Kelas B juga dan meluncurkan Kelas C menggunakan startActivityForResult. Setelah Anda mendapatkan hasilnya di Kelas B kemudian atur hasilnya di sana (untuk Kelas A) berdasarkan hasil dari Kelas C. Saya belum mencoba ini tetapi saya pikir ini harus bekerja.

Hal lain yang perlu diwaspadai adalah bahwa Aktivitas A tidak boleh menjadi aktivitas Instansi tunggal. Agar startActivityForResult berfungsi, Kelas B Anda harus menjadi sub aktivitas untuk Aktivitas A dan yang tidak mungkin dilakukan dalam aktivitas instance tunggal, Activity baru (Kelas B) dimulai dalam tugas baru.

Prashast
sumber
1
Karena Kelas B adalah TabActivity dan Kelas C adalah Tab dalam aktivitas itu, Anda tidak dapat melakukan startActivityForResult di Kelas B. Tidak ada satu pun kegiatan saya yang merupakan Aktivitas Instans Tunggal.
Cameron McBride
-1

Untuk memulai Kegiatan 2 dari Aktivitas 1 dan mendapatkan hasil, Anda bisa menggunakan startActivityForResult dan mengimplementasikan onActivityResult di Aktivitas 1 dan menggunakan setResult di Activity2.

Intent intent = new Intent(this, Activity2.class);
intent.putExtra(NUMERO1, numero1);
intent.putExtra(NUMERO2, numero2);
//startActivity(intent);
startActivityForResult(intent, MI_REQUEST_CODE);
Aplikasi-Perangkat Lunak Pabrik
sumber