Android开发:从Second Activity向Third Activity传值失败求助
解决SecondActivity到ThirdActivity的数据传递问题
嘿,我来帮你搞定这个数据传递的问题!先看看你代码里的几个关键问题:
- 在
SecondActivity的onClickTwo方法里,你同时给MainActivity和ThirdActivity设置了setResult,但实际上finish()后只会回到MainActivity,ThirdActivity根本没被启动,而且setResult()只能生效一次,后面的会覆盖前面的,这完全走错了传递路径。 ThirdActivity的onActivityResult方法根本不会触发,因为你是从MainActivity直接启动它的,不是通过startActivityForResult从SecondActivity跳转过来的,所以这个方法完全没用。
下面给你两种简单可行的解决方案,你可以根据需求选择:
方案一:通过MainActivity中转数据(适合临时传递,不需要持久化)
这个方案的核心是让MainActivity保存从SecondActivity拿到的完整用户数据,跳转ThirdActivity时直接把数据传过去。
1. 修改MainActivity
添加成员变量存储完整用户信息,修改跳转ThirdActivity的逻辑:
public class MainActivity extends AppCompatActivity { // 新增成员变量保存用户完整信息 private String userName; private String userEmail; private int userPhone; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void onClick(View view){ startActivityForResult(new Intent(getApplicationContext(),SecondActivity.class),999); } public void onClickText(View v) { // 直接启动ThirdActivity,把保存的完整数据传递过去 Intent intent = new Intent(getApplicationContext(), ThirdActivity.class); intent.putExtra("Name", userName); intent.putExtra("Email", userEmail); intent.putExtra("Phone", userPhone); startActivity(intent); // 这里不需要用startActivityForResult,因为不需要返回结果 } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode == 999 && resultCode == RESULT_OK) { TextView contactView = findViewById(R.id.contactDisplay); // 保存所有数据到成员变量 userName = data.getStringExtra("Name"); userEmail = data.getStringExtra("Email"); userPhone = data.getIntExtra("Phone", 0); // 第二个参数是默认值,防止空输入崩溃 contactView.setText(userName); } } }
2. 修改SecondActivity
返回所有用户数据给MainActivity,去掉多余的ThirdActivity Intent:
public class SecondActivity extends AppCompatActivity { private EditText textPersonName; private EditText number; private EditText textEmailAddress; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); // 建议在onCreate里初始化控件,避免重复findViewById textPersonName = findViewById(R.id.name); number = findViewById(R.id.number); textEmailAddress = findViewById(R.id.email); } public void onClickTwo(View view) { String textName = textPersonName.getText().toString(); String emailAddress = textEmailAddress.getText().toString(); // 处理空输入,防止NumberFormatException崩溃 int phoneNumber = 0; if(!number.getText().toString().isEmpty()){ phoneNumber = Integer.valueOf(number.getText().toString()); } showToast(textName + " added"); // 只返回给MainActivity所有数据 Intent backMain = new Intent(this, MainActivity.class); backMain.putExtra("Name", textName); backMain.putExtra("Email", emailAddress); backMain.putExtra("Phone", phoneNumber); setResult(RESULT_OK, backMain); finish(); } private void showToast(String text) { Toast.makeText(this, text, Toast.LENGTH_LONG).show(); } }
3. 修改ThirdActivity
直接在onCreate里从启动Intent获取数据,删掉没用的onActivityResult:
public class ThirdActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_third); // 从启动当前Activity的Intent中获取数据 Intent intent = getIntent(); if(intent != null){ String name = intent.getStringExtra("Name"); String email = intent.getStringExtra("Email"); int phone = intent.getIntExtra("Phone", 0); TextView contact = findViewById(R.id.contactNameView); contact.setText(name); TextView phoneView = findViewById(R.id.phoneView); phoneView.setText(String.valueOf(phone)); // 注意:int要转成String,否则会当成资源ID导致显示异常 TextView emailView = findViewById(R.id.emailView); emailView.setText(email); } } }
方案二:用SharedPreferences持久化数据(适合需要长期保存用户信息的场景)
如果希望用户关闭App后再次打开,数据依然存在,可以用SharedPreferences来存储数据。
1. 修改SecondActivity
把用户数据保存到SharedPreferences:
public void onClickTwo(View view) { String textName = textPersonName.getText().toString(); String emailAddress = textEmailAddress.getText().toString(); int phoneNumber = 0; if(!number.getText().toString().isEmpty()){ phoneNumber = Integer.valueOf(number.getText().toString()); } showToast(textName + " added"); // 保存数据到SharedPreferences SharedPreferences sp = getSharedPreferences("UserInfo", MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); editor.putString("Name", textName); editor.putString("Email", emailAddress); editor.putInt("Phone", phoneNumber); editor.apply(); // 异步保存,比commit更高效 // 返回名字给MainActivity Intent backMain = new Intent(this, MainActivity.class); backMain.putExtra("Name", textName); setResult(RESULT_OK, backMain); finish(); }
2. 修改ThirdActivity
从SharedPreferences读取数据:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_third); // 从SharedPreferences读取数据 SharedPreferences sp = getSharedPreferences("UserInfo", MODE_PRIVATE); String name = sp.getString("Name", ""); // 第二个参数是默认值,避免空指针 String email = sp.getString("Email", ""); int phone = sp.getInt("Phone", 0); TextView contact = findViewById(R.id.contactNameView); contact.setText(name); TextView phoneView = findViewById(R.id.phoneView); phoneView.setText(String.valueOf(phone)); TextView emailView = findViewById(R.id.emailView); emailView.setText(email); }
额外注意事项
- 处理手机号空输入:如果用户没填手机号,直接转int会抛出
NumberFormatException,所以一定要加空判断。 - int转String:给TextView设置int类型数据时,必须用
String.valueOf()转成字符串,否则系统会把这个int当成资源ID去查找对应的字符串,导致显示空白或者崩溃。
内容的提问来源于stack exchange,提问作者JoeMan
相关产品推荐
相关产品推荐

