Gửi dữ liệu trở lại Hoạt động chính trong Android


295

Tôi có hai hoạt động: hoạt động chính và hoạt động trẻ em.
Khi tôi nhấn một nút trong hoạt động chính, hoạt động con được khởi chạy.

Bây giờ tôi muốn gửi một số dữ liệu trở lại màn hình chính. Tôi đã sử dụng lớp Bundle, nhưng nó không hoạt động. Nó ném một số ngoại lệ thời gian chạy.

Có giải pháp nào cho điều này?



Một mẹo nữa xác định một ArrayList trong hoạt động chính của bạn và làm cho nó tĩnh để bạn có thể truy cập nó trong hoạt động thứ hai sau đó thêm dữ liệu vào đó bạn muốn gửi đến hoạt động chính sau đó bạn truy cập vào hoạt động chính
Abhishek Yadav

Abhishek Yadav, nếu hoạt động chính của bạn sẽ phá hủy (gọi lại onDestroy ()). Tôi nghĩ rằng đó không phải là lời khuyên tốt.
Leontsev Anton

Câu trả lời:


473

Có một vài cách để đạt được những gì bạn muốn, tùy thuộc vào hoàn cảnh.

Kịch bản phổ biến nhất (giống như kịch bản của bạn) là khi một Hoạt động con được sử dụng để nhận đầu vào của người dùng - chẳng hạn như chọn một liên hệ từ danh sách hoặc nhập dữ liệu vào hộp thoại. Trong trường hợp này bạn nên sử dụngstartActivityForResult để khởi chạy Hoạt động của con bạn.

Điều này cung cấp một đường ống để gửi dữ liệu trở lại Hoạt động chính bằng cách sử dụng setResult. Phương thức setResult nhận giá trị kết quả int và Ý định được chuyển trở lại Hoạt động gọi.

Intent resultIntent = new Intent();
// TODO Add extras or a data URI to this intent as appropriate.
resultIntent.putExtra("some_key", "String data"); 
setResult(Activity.RESULT_OK, resultIntent);
finish();

Để truy cập dữ liệu trả về trong ghi đè Hoạt động gọi onActivityResult. RequestCode tương ứng với số nguyên được truyền trong startActivityForResultcuộc gọi, trong khi Intent result và data được trả về từ Activity con.

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);
  switch(requestCode) {
    case (MY_CHILD_ACTIVITY) : {
      if (resultCode == Activity.RESULT_OK) {
        // TODO Extract the data returned from the child Activity.
        String returnValue = data.getStringExtra("some_key");
      }
      break;
    } 
  }
}

4
để hoàn thiện người ta nên đề cập đến nơi tốt nhất để thực hiện cuộc gọi kết thúc () là gì? Nó có thể rõ ràng cho các chuyên gia, nhưng đối với người mới bắt đầu sẽ là tốt để biết mà không cần tham khảo các nguồn bổ sung.
Califf

1
@jelmoodjasser Tôi đã mất một chút để tìm hiểu, nhưng về cơ bản khi bạn bắt đầu hoạt động mới với Ý định, bạn cần sử dụng startActivityForResultchức năng thay vì chỉ startActivity. Một ví dụ có thể là startActivityForResult(myIntent, 2);2 là mã kết quả, có thể thay thế MY_CHILD_ACTIVITYcho câu lệnh chuyển đổi ở trên.
Tiêu điểm

khi hoạt động thứ hai kết thúc và trở lại hoạt động đầu tiên thì làm thế nào để đặt requestCode thành hoạt động thứ hai trước khi kết thúc nó .... để sử dụng nó cho onActivityResult trong FirstActivity
Ahamadullah Saikat

Là ý định bắt buộc? Nếu tôi không có gì để gửi lại, tôi có cần gửi lại không?
Bagus Aji Santoso

Mục đích @BagusAjiSantoso là tùy chọn, chỉ cần thiết nếu bạn có bất cứ điều gì để gửi lại.
Narendra Singh

186

Hoạt động 1 sử dụng startActivityForResult :

startActivityForResult(ActivityTwo, ActivityTwoRequestCode);

Hoạt động 2 được khởi chạy và bạn có thể thực hiện thao tác, để đóng Hoạt động thực hiện việc này:

Intent output = new Intent();
output.putExtra(ActivityOne.Number1Code, num1);
output.putExtra(ActivityOne.Number2Code, num2);
setResult(RESULT_OK, output);
finish();

Hoạt động 1 - trở về từ hoạt động trước sẽ gọi onActivityResult :

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == ActivityTwoRequestCode && resultCode == RESULT_OK && data != null) {
        num1 = data.getIntExtra(Number1Code);
        num2 = data.getIntExtra(Number2Code);
    }
}

CẬP NHẬT: Trả lời nhận xét của Seenu69, Trong hoạt động hai,

int result = Integer.parse(EditText1.getText().toString()) 
           + Integer.parse(EditText2.getText().toString());
output.putExtra(ActivityOne.KEY_RESULT, result);

Sau đó, trong hoạt động một,

int result = data.getExtra(KEY_RESULT);

Xin chào, tôi đánh giá cao bạn đã trả lời câu hỏi của tôi. Mã này không đủ cho tôi. Tôi muốn bổ sung được thực hiện trong chính hoạt động thứ hai và kết quả sẽ được trả về MainActivity thông qua phương thức onActivityResult. Chẳng hạn, chỉ có nút trong Hoạt động chính đưa bạn đến hoạt động thứ hai khi nhấp vào nó, có hai số được nhập thông qua tiện ích chỉnh sửa, logic bổ sung được thực hiện trong chính hoạt động thứ hai và cuối cùng kết quả được trả về MainActivity. Hiểu rồi?
Seenu69

2
Trong trường hợp đó trong hoạt động thứ hai, bạn sẽ thực hiện tính toán và lưu trữ kết quả theo ý định với putExtra (). Tôi đã chỉnh sửa câu trả lời của mình ở trên
jimmithy

68

Gửi lại dữ liệu

Nó giúp tôi nhìn thấy mọi thứ trong bối cảnh. Đây là một dự án đơn giản hoàn chỉnh để gửi dữ liệu trở lại. Thay vì cung cấp các tệp bố cục xml, đây là một hình ảnh.

nhập mô tả hình ảnh ở đây

Hoạt động chủ yêu

  • Bắt đầu hoạt động thứ hai với startActivityForResult , cung cấp cho nó mã kết quả tùy ý.
  • Ghi đè onActivityResult . Điều này được gọi khi Hoạt động thứ hai kết thúc. Bạn có thể chắc chắn rằng đó thực sự là Hoạt động thứ hai bằng cách kiểm tra mã yêu cầu. (Điều này hữu ích khi bạn bắt đầu nhiều hoạt động khác nhau từ cùng một hoạt động chính.)
  • Trích xuất dữ liệu bạn nhận được từ sự trở lại Intent. Dữ liệu được trích xuất bằng cặp khóa-giá trị.

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private static final int SECOND_ACTIVITY_REQUEST_CODE = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // "Go to Second Activity" button click
    public void onButtonClick(View view) {

        // Start the SecondActivity
        Intent intent = new Intent(this, SecondActivity.class);
        startActivityForResult(intent, SECOND_ACTIVITY_REQUEST_CODE);
    }

    // This method is called when the second activity finishes
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // Check that it is the SecondActivity with an OK result
        if (requestCode == SECOND_ACTIVITY_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {

                // Get String data from Intent
                String returnString = data.getStringExtra("keyName");

                // Set text view with string
                TextView textView = (TextView) findViewById(R.id.textView);
                textView.setText(returnString);
            }
        }
    }
}

Hoạt động thứ hai

  • Đặt dữ liệu mà bạn muốn gửi lại cho hoạt động trước đó vào một Intent. Dữ liệu được lưu trữ trongIntent sử dụng khóa-giá trị.
  • Đặt kết quả thành RESULT_OK và thêm ý định giữ dữ liệu của bạn.
  • Gọi finish()để đóng Hoạt động thứ hai.

Thứ haiActivity.java

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
    }

    // "Send text back" button click
    public void onButtonClick(View view) {

        // Get the text from the EditText
        EditText editText = (EditText) findViewById(R.id.editText);
        String stringToPassBack = editText.getText().toString();

        // Put the String to pass back into an Intent and close this activity
        Intent intent = new Intent();
        intent.putExtra("keyName", stringToPassBack);
        setResult(RESULT_OK, intent);
        finish();
    }
}

Ghi chú khác

  • Nếu bạn ở trong một mảnh vỡ, nó sẽ không biết ý nghĩa của RESULT_OK. Chỉ cần sử dụng tên đầy đủ : Activity.RESULT_OK.

Xem thêm


Đó là một lời giải thích rất rõ ràng bằng văn bản. Làm tốt!
Kingsley Ijike

29

FirstActivity sử dụng startActivityForResult:

Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivityForResult(intent, int requestCode); // suppose requestCode == 2

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 2)
    {
        String message=data.getStringExtra("MESSAGE");
    }
}

Trên cuộc gọi SecondActivity setResult () onClick event hoặc onBackPression ()

Intent intent=new Intent();
intent.putExtra("MESSAGE",message);
setResult(Activity.RESULT_OK, intent);

Có phải là resultCode của requestCode không?
Engr Syed Rowshan Ali

15

Gọi hoạt động con Ý định sử dụng lệnh gọi phương thức startActivityForResult ()

Có một ví dụ về điều này ở đây: http://developer.android.com/training/notepad/notepad-ex2.html

và trong phần "Trả về kết quả từ màn hình" của điều này: http://developer.android.com/guide/faq/commont Nhiệm.html#opennewscreen


Vâng, tôi đồng tình với cbrulak, liên kết đến các tài liệu hữu ích hơn nhiều so với câu trả lời.
george_h

Các liên kết đang hiển thị một số điều chung bây giờ. Nội dung có thể được thay đổi, vui lòng cập nhật nội dung hoặc xóa câu trả lời cho cộng đồng
Manoranjan

7

Tôi đã tạo lớp demo đơn giản để bạn tham khảo tốt hơn.

FirstActivity.java

 public class FirstActivity extends AppCompatActivity {

    private static final String TAG = FirstActivity.class.getSimpleName();
    private static final int REQUEST_CODE = 101;
    private Button btnMoveToNextScreen;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnMoveToNextScreen = (Button) findViewById(R.id.btnMoveToNext);
        btnMoveToNextScreen.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent mIntent = new Intent(FirstActivity.this, SecondActivity.class);
                startActivityForResult(mIntent, REQUEST_CODE);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if(resultCode == RESULT_OK){
            if(requestCode == REQUEST_CODE && data !=null) {
                String strMessage = data.getStringExtra("keyName");
                Log.i(TAG, "onActivityResult: message >>" + strMessage);
            }
        }

    }
}

Và đây là SecondActivity.java

public class SecondActivity extends AppCompatActivity {

    private static final String TAG = SecondActivity.class.getSimpleName();
    private Button btnMoveToPrevious;
    private EditText editText;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        editText = (EditText) findViewById(R.id.editText);

        btnMoveToPrevious = (Button) findViewById(R.id.btnMoveToPrevious);
        btnMoveToPrevious.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String message = editText.getEditableText().toString();

                Intent mIntent = new Intent();
                mIntent.putExtra("keyName", message);
                setResult(RESULT_OK, mIntent);
                finish();

            }
        });

    }
}

3
giải thích tốt!
Radhey

5

Trong hoạt động đầu tiên, bạn có thể gửi ý định sử dụng startActivityForResult()và sau đó nhận kết quả từ hoạt động thứ hai sau khi sử dụng xong setResult.

MainActivity. Class

public class MainActivity extends AppCompatActivity {

    private static final int SECOND_ACTIVITY_RESULT_CODE = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // "Go to Second Activity" button click
    public void onButtonClick(View view) {

        // Start the SecondActivity
        Intent intent = new Intent(this, SecondActivity.class);
        // send intent for result 
        startActivityForResult(intent, SECOND_ACTIVITY_RESULT_CODE);
    }

    // This method is called when the second activity finishes
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // check that it is the SecondActivity with an OK result
        if (requestCode == SECOND_ACTIVITY_RESULT_CODE) {
            if (resultCode == RESULT_OK) {

                // get String data from Intent
                String returnString = data.getStringExtra("keyName");

                // set text view with string
                TextView textView = (TextView) findViewById(R.id.textView);
                textView.setText(returnString);
            }
        }
    }
}

SecondActivity. Class

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
    }

    // "Send text back" button click
    public void onButtonClick(View view) {

        // get the text from the EditText
        EditText editText = (EditText) findViewById(R.id.editText);
        String stringToPassBack = editText.getText().toString();

        // put the String to pass back into an Intent and close this activity
        Intent intent = new Intent();
        intent.putExtra("keyName", stringToPassBack);
        setResult(RESULT_OK, intent);
        finish();
    }
}

1

Tất cả những câu trả lời này đang giải thích kịch bản hoạt động thứ hai của bạn cần được hoàn thành sau khi gửi dữ liệu.

Nhưng trong trường hợp nếu bạn không muốn kết thúc hoạt động thứ hai và muốn gửi lại dữ liệu trước thì bạn có thể sử dụng BroadCastReceiver.

Trong hoạt động thứ hai -

Intent intent = new Intent("data");
intent.putExtra("some_data", true);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

Trong hoạt động đầu tiên-

private BroadcastReceiver tempReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // do some action
    }
};

Đăng ký người nhận trong onCreate () -

 LocalBroadcastManager.getInstance(this).registerReceiver(tempReceiver,new IntentFilter("data"));

Hủy đăng ký nó trong onDestroy ()


0

Một cách khác để đạt được kết quả mong muốn có thể tốt hơn tùy thuộc vào tình huống của bạn là tạo giao diện người nghe.

Bằng cách làm cho hoạt động cha mẹ lắng nghe một giao diện được kích hoạt bởi hoạt động con trong khi truyền dữ liệu cần thiết làm tham số có thể tạo ra một tình huống tương tự


-1

Có một số cách để làm điều này. 1. bằng cách sử dụng startActivityForResult () được giải thích rất rõ trong các câu trả lời trên.

  1. bằng cách tạo các biến tĩnh trong lớp "Utils" hoặc bất kỳ lớp nào khác của riêng bạn. Ví dụ: tôi muốn chuyển studentId từ ActivityB sang ActivityA. Trước tiên, ActivityA của tôi đang gọi ActivityB. Sau đó, bên trong ActivityB đặt studentId (là trường tĩnh trong Utils. Class). Giống như Utils.STUDENT_ID = "1234"; sau đó trong khi quay trở lại ActivityA, hãy sử dụng studentId được lưu trữ trong Utils.STUDENT_ID.

  2. bằng cách tạo một phương thức getter và setter trong Lớp ứng dụng của bạn.

như thế này:

public class MyApplication extends Application {

    private static MyApplication instance = null;
    private String studentId="";

    public static MyApplication getInstance() {
        return instance;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
    }

    public void setStudentId(String studentID){
        this.studentId=studentID;
    }

    public String getStudentId(){
        return this.studentId;
    }
}

vậy là xong chỉ cần đặt dữ liệu bên trong khi bạn ở trong ActivityB và sau khi quay lại ActivityA, hãy lấy dữ liệu.


-1

Chỉ là một chi tiết nhỏ mà tôi nghĩ là thiếu trong các câu trả lời ở trên.

Nếu hoạt động của con bạn có thể được mở từ nhiều hoạt động cha mẹ thì bạn có thể kiểm tra xem bạn có cần phải làm setResulthay không, dựa trên việc hoạt động của bạn đã được mở bởi startActivityhay startActivityForResult. Bạn có thể đạt được điều này bằng cách sử dụng getCallingActivity(). Thêm thông tin ở đây .


-2

Sử dụng sharedPreferences và lưu dữ liệu của bạn và truy cập nó từ bất cứ đâu trong ứng dụng

lưu lại ngày như thế này

SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putString(key, value);
    editor.commit();

Và nhận dữ liệu như thế này

SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
    String savedPref = sharedPreferences.getString(key, "");
    mOutputView.setText(savedPref);

6
Điều này sẽ phù hợp hơn nếu hoạt động thứ hai đang thiết lập thay đổi / cài đặt vĩnh viễn trong ứng dụng.
bỏ

Điều này có hoạt động nếu tôi muốn chia sẻ dữ liệu giữa 2 ứng dụng Android khác nhau không? Một người gọi là thư viện?
joey rohan

21
Đây là lạm dụng SharedPreferences.
Eran Goldin

1
Sử dụng phương pháp này để chỉ truyền dữ liệu giữa hai hoạt động (câu hỏi ban đầu của OP) giống như lạm dụng SharedPreferences. Điều này không có nghĩa là điều này và hệ thống phải thực hiện quá nhiều công việc (ghi xml vào bộ lưu trữ và đọc lại) cho một nhiệm vụ đơn giản như truyền dữ liệu giữa hai hoạt động.
Sudara
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.