将数据发送回Android中的主活动


294

我有两个活动:主要活动和儿童活动。
当我在主要活动中按一个按钮时,子活动将启动。

现在,我想将一些数据发送回主屏幕。我使用了Bundle类,但是没有用。它引发一些运行时异常。

有什么解决办法吗?



还有一个技巧在您的主要活动中定义一个ArrayList并将其设置为静态,以便您可以在第二个活动中对其进行访问,然后在其中添加要发送到主要活动的数据,然后在主要活动中对其进行访问
Abhishek Yadav

Abhishek Yadav,如果您的主要活动将要销毁(onDestroy()回调)。我认为这不是很好的建议。
Leontsev Anton

Answers:


471

根据情况,有两种方法可以实现您想要的。

最常见的情况(这听起来像您的情况)是使用子Activity来获取用户输入时,例如从列表中选择联系人或在对话框中输入数据。在这种情况下,您应该startActivityForResult用来启动子活动。

这提供了使用来将数据发送回主活动的管道setResult。setResult方法采用一个int结果值和一个Intent,该Intent传递回调用方Activity。

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

要访问在调用Activity中返回的数据,请重写onActivityResult。requestCode对应于startActivityForResult调用中传递的整数,而resultCode和数据Intent是从子Activity返回的。

@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
为了完整起见,应该提到在哪里调用finish()的最佳位置是什么?对于专家来说也许很清楚,但是对于初学者来说,如果不参考其他资源,将是很好的了解。
卡利夫(Califf)

1
@jelmoodjasser我花了一点时间来弄清楚,但是基本上,当您使用Intent启动新活动时,您需要使用该startActivityForResult函数而不是just startActivity。例如startActivityForResult(myIntent, 2);,结果代码为2,可以MY_CHILD_ACTIVITY在上面的switch语句中代替。
聚焦

当第二个活动结束并返回第一个活动时,如何在完成之前将requestCode设置为第二个活动....在FirstActivity中将其用于onActivityResult
Ahamadullah Saikat 17-10-9

目的是强制性的吗?如果我没有任何东西可以寄回,我是否需要空洞的意图寄回?
Bagus Aji Santoso

@BagusAjiSantoso意图是可选的,仅当您有任何东西要发回时才需要。
Narendra Singh

186

活动1使用startActivityForResult

startActivityForResult(ActivityTwo, ActivityTwoRequestCode);

活动2启动,您可以执行操作,要关闭活动,请执行以下操作:

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

活动1-从上一个活动返回后,将调用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);
    }
}

更新:回答Seenu69的评论,在第二场活动中,

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

然后在活动一中

int result = data.getExtra(KEY_RESULT);

您好,我感谢您回答我的问题。此代码对我来说还不够。我希望在第二个活动本身中执行加法,并且应该通过onActivityResult方法将结果返回给MainActivity。例如,主活动中只有一个按钮,单击该按钮会将您带到第二个活动,通过editText小部件输入了两个数字,第二个活动本身执行了加法运算,最后将结果返回给MainActivity。得到它了?
Seenu69 '11

2
在这种情况下,在第二个活动中,您将执行计算并将结果通过putExtra()存储在意图中。我已经在上方编辑了答案
jimmithy 2012年

67

发回数据

它帮助我从上下文中看到事物。这是一个用于发送回数据的完整简单项目。这是一个图像,而不是提供xml布局文件。

在此处输入图片说明

主要活动

  • 从开始第二个活动startActivityForResult,为其提供任意结果代码。
  • 覆盖onActivityResult。当第二活动完成时,将调用此方法。您可以通过检查请求代码来确保它实际上是第二个活动。(当您从同一个主活动开始多个不同的活动时,这很有用。)
  • 提取您从return中获得的数据Intent。使用键值对提取数据。

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

第二次活动

  • 将要发送回上一活动的数据放入中Intent。数据Intent使用键值对存储。
  • 将结果设置为 RESULT_OK并添加保存数据的意图。
  • 调用finish()以关闭第二个活动。

SecondActivity.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();
    }
}

其他注意事项

  • 如果您在Fragment中,则不会知道的含义RESULT_OK。只需使用全名:Activity.RESULT_OK

也可以看看


这是一个写得很好的明确解释。做得好!
金斯利·伊吉克

29

FirstActivity使用startActivityForResult:

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

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

在SecondActivity上调用setResult()onClick事件或onBackPressed()

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

是requestCode的resultCode吗?
Engr Syed Rowshan Ali

15

使用startActivityForResult()方法调用来调用子活动Intent

这里有一个示例:http : //developer.android.com/training/notepad/notepad-ex2.html

并在其“从屏幕返回结果”中:http : //developer.android.com/guide/faq/commontasks.html#opennewscreen


是的,我同意cbrulak的观点,指向文档的链接比答案更有帮助。
george_h 2013年

这些链接现在显示了一些常规内容。内容可能会更改,请更新或删除社区的答案
Manoranjan

7

我创建了简单的演示类,供您更好地参考。

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

    }
}

这是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
很好的解释!
Radhey

5

在第一个活动中,您可以使用发送意图 startActivityForResult(),然后在使用完后从第二个活动中获取结果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

所有这些答案都说明了发送数据后需要完成第二项活动的情况。

但是,如果您不想完成第二个活动,而又想将数据发送回去,则可以使用BroadCastReceiver。

在第二活动中-

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

在第一个活动中-

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

在onCreate()中注册接收者

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

在onDestroy()中注销它


0

根据您的情况可能更好的另一种获得所需结果的方法是创建一个侦听器界面。

通过使父活动监听由子活动触发的接口,同时将所需数据作为参数传递,可以创建一组相似的情况


-1

有一些方法可以做到这一点。1.通过使用上述答案中很好解释的startActivityForResult()。

  1. 通过在“ Utils”类或您自己的任何其他类中创建静态变量。例如我想将StudentId从ActivityB传递给ActivityA。首先我的ActivityA正在调用ActivityB。然后在ActivityB内设置studentId(这是Utils.class中的静态字段)。像这样的Utils.STUDENT_ID =“ 1234”; 然后返回到ActivityA时,使用存储在Utils.STUDENT_ID中的studentId。

  2. 通过在应用程序类中创建一个getter和setter方法。

像这样:

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

这样就完成了。只需在u处于ActivityB中时在内部设置数据,然后返回到ActivityA即可获取数据。


-1

我认为以上答案中只缺少一个小细节。

如果可以从多个父活动中打开您的子活动,则可以setResult根据您的活动是否由startActivity或打开来检查是否需要做startActivityForResult。您可以使用来实现getCallingActivity()。更多信息在这里


-2

使用sharedPreferences并保存数据并从应用程序中的任何位置访问

这样保存日期

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

并像这样接收数据

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

6
如果第二项活动是在应用程序中设置永久更改/设置,则这将更为合适。
elimirks 2013年

如果我想在2个不同的android应用之间共享数据,是否可以正常工作?
joey rohan 2014年

21
这是SharedPreferences滥用。
伊兰·戈尔丁

1
使用此方法仅在两个活动之间传递数据(OP的原始问题)就像在滥用SharedPreferences。这并不意味着要这样做,并且系统必须完成过多的工作(在存储中写入xml并再次读取它)来完成简单的任务,例如在两个活动之间传递数据。
Sudara
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.