Làm cách nào để trả về kết quả (startActivityForResult) từ Hoạt động của Tabhost?


275

Tôi có 3 lớp trong ví dụ của mình: Lớp A, hoạt động chính. Lớp A gọi một startActivityForResult:

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

Lớp B, lớp này là TabActivity:

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

Lớp C, lớp này là một Hoạt động thường xuyên:

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

onActivityResult được gọi trong Lớp A, nhưng Mã kết quả là RESULT_CANCELED thay vì RESULT_OKvà mục đích trả về là null. Làm cách nào để tôi trả lại một cái gì đó từ Hoạt động bên trong Tabhost?

Tôi nhận ra rằng vấn đề là Lớp C của tôi thực sự đang chạy bên trong Lớp B, và Lớp B là thứ đang quay trở RESULT_CANCELEDlại Lớp A. Tôi chỉ chưa biết một công việc xung quanh.

Câu trả lời:


366

Ôi Chúa ơi! Sau khi dành vài giờ và tải xuống các nguồn Android, cuối cùng tôi cũng đã đi đến một giải pháp.

Nếu bạn nhìn vào lớp Activity, bạn sẽ thấy, finish()phương thức đó chỉ gửi lại kết quả nếu có một thuộc mParenttính được đặt thành null. Nếu không thì kết quả bị mất.

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);
    }
}

Vì vậy, giải pháp của tôi là đặt kết quả cho hoạt động chính nếu có, như thế:

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

Tôi hy vọng điều đó sẽ hữu ích nếu ai đó tìm kiếm vấn đề này một lần nữa.


1
Tôi đã đăng một giải pháp hacky ở đây, nó đơn giản và liên quan đến một hoạt động minh bạch không có nội dung - nó có các chức năng vòng đời bình thường và làm cho mọi thứ dễ dàng hơn. stackoverflow.com/questions/7812120/iêu
CQM

Thật tuyệt vời! Cảm ơn bạn, cảm ơn bạn, cảm ơn bạn! Nó hoạt động hoàn hảo và rất ít phiền phức. Tôi đã ghi đè các phương thức setResult () thông thường cho tất cả các Hoạt động của tôi với viên ngọc nhỏ này. Cảm ơn bạn!
Scott Biggie

Tôi đã sử dụng giải pháp của bạn, nhưng mã của tôi không bắt được phương thức onactivityresult khi quay lại. Xin hãy giúp tôi .. tôi có cần sử dụng cái gì khác không?
skygeek

11
Tại sao việc trả lại kết quả trong một Hoạt động không được ghi lại ở bất kỳ đâu trong hướng dẫn API, khiến tôi thấy kỳ lạ.
alex.p

Chỉ trích! Làm tốt lắm, Illya! Cảm ơn
Sirelon

64

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

Với một sửa đổi nhỏ cho "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();
}

2
Đơn giản, setResultlà điều chính. Đặt nó thành một cái gì đó, hoặc một giá trị chẳng hạn RESULT_OKvà bạn tốt để đi; setResult(RESULT_OK);. Đã giúp tôi, +1
Afzaal Ahmad Zeeshan

16

Ý định.FLAG_ACTIVITY_FORWARD_RESULT?

Nếu được đặt và mục đích này đang được sử dụng để khởi chạy một hoạt động mới từ một hoạt động hiện có, thì mục tiêu trả lời của hoạt động hiện tại sẽ được chuyển sang hoạt động mới.


1

Bạn cũng có thể triển khai onActivityResult trong Class B và khởi chạy Class C bằng startActivityForResult. Khi bạn nhận được kết quả trong Lớp B, sau đó đặt kết quả ở đó (cho Lớp A) dựa trên kết quả của Lớp C. Tôi chưa thử điều này nhưng tôi nghĩ việc này sẽ hiệu quả.

Một điều khác cần chú ý là Hoạt động A không nên là một hoạt động Đơn lẻ. Để startActivityForResult hoạt động, lớp B của bạn cần phải là một hoạt động phụ cho Hoạt động A và điều đó là không thể trong một hoạt động cá thể, Hoạt động mới (Lớp B) bắt đầu trong một nhiệm vụ mới.


1
Vì Lớp B là TabActivity và Class C là Tab trong hoạt động đó, bạn không thể thực hiện startActivityForResult trong Lớp B. Không có hoạt động nào của tôi là Hoạt động sơ thẩm.
Cameron McBride

-1

Để bắt đầu Hoạt động 2 từ Hoạt động 1 và nhận kết quả, bạn có thể sử dụng startActivityForResult và triển khai onActivityResult trong Hoạt động 1 và sử dụng setResult trong Hoạt động 2.

Intent intent = new Intent(this, Activity2.class);
intent.putExtra(NUMERO1, numero1);
intent.putExtra(NUMERO2, numero2);
//startActivity(intent);
startActivityForResult(intent, MI_REQUEST_CODE);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.