Android四大组件之Activity详解——传值和获取结果
废话不多说,先来看效果图
项目源码:
http://download.csdn.net/detail/ginodung/8331535
程序说明:
- 在MainActivity中输入用户名和密码,然后提交到SecondActivity
- 在SecondActivity中获取提交的数据,通过Toast显示该数据
- 在SecondActivity设置新的用户名和密码,然后返回给MainActivity
- MainActivity获取到SecondActivity返回的数据后从新设置用户名和密码的值,然后用Toast显示其他返回值
用到的知识:
主要还是基于Intent的使用,因为Intent本身就是一个信使对象。
基本原理:
- 使用Intent的putXxxExtra()方法保存值
- Bundle对象的使用:
- 使用Intent的putExtras(Bundle bundle)方法
- 使用Intent的setData()方法
- startActivityForResult()方法的使用
- onActivityResult()方法的使用
代码分析:
先来看一下MainActivity的代码
package com.example.activitydemo; import java.util.List; import android.app.Activity; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class MainActivity extends Activity { private EditText nameText; private EditText passText; public static final int REQUESTCODE = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 查找我们在布局中创建的按钮 Button startSecondActivity = (Button) findViewById(R.id.btnlogin); nameText = (EditText) findViewById(R.id.username); passText = (EditText) findViewById(R.id.password); // 为按钮绑定点击事件 startSecondActivity.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String username = nameText.getText().toString(); String password = passText.getText().toString(); Intent intent = new Intent( "com.example.activitydemo.mysecondactivity"); // 把要发送的数据以键值对的方式保存在intent对象中 intent.putExtra("username", username); intent.putExtra("password", password); // 创建PackageManager类 PackageManager packageManager = getPackageManager(); // 获取包含能处理给定intent的activity列表 List<ResolveInfo> activities = packageManager .queryIntentActivities(intent, 0); if (activities.size() > 0) // 启动SecondActivity startActivityForResult(intent, REQUESTCODE); else Toast.makeText(getBaseContext(), "Activity not found", Toast.LENGTH_SHORT).show(); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUESTCODE) { if (resultCode == RESULT_OK) { // 获取从SecondActivity通过Bundle返回的值 Bundle extras = data.getExtras(); String newUserName = extras.getString("newusername"); String newPassword = extras.getString("newPassword"); nameText.setText(newUserName); passText.setText(newPassword); // 获取从SecondActivity通过setData返回的值 String strFromSec = data.getData().toString(); Toast.makeText(this, strFromSec, Toast.LENGTH_SHORT).show(); } } } }
看上面的代码,主要的还是下面的两句
intent.putExtra("username", username);
intent.putExtra("password", password);
我们使用putExtra方法把数据保存到要启动的Intent中去,
然后使用startActivityForResult方法启动这个Intent.
这里要说一下startActivityForResult方法,当我们需要从被启动的Activity获取返回值的时候就应该调用这个方法
它有两个参数,第一个Intent就不用说了.主要是第二个参数requestcode,它是一个整数。
requestCode参数的作用是:
当出现调用多个有返回值的Activity时,我们就需要requestCode去辨认是哪一个Activity所返回的值
当这个参数大于零的时候它才有意义,当requestCode设置为-1的时候,
就相当于调用startActivity方法。
再看onActivityResult方法,这个方法是响应其他Activity的setResult方法的,
意思就是当一个有返回值的Activity返回时会调用onActivityResult方法,所以我们必须实现这个方法
在这个方法中,我们通过requestCode识别是哪一个Activity返回的值,
以及使用resultCode检测数据是否成功返回。
onActivityResult中其他的内容我们先不说,先看SecondActivity的内容
package com.example.activitydemo; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class SecondActivity extends Activity { private EditText userNameEditText; private EditText passwordEditText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 绑定activity_second布局到SecondActivity setContentView(R.layout.activity_second); // 获取传递过来的Intent对象,这个对象是MainActivity从传递过来的 Intent intent = getIntent(); // 从Intent对象中获取数据 String username = intent.getStringExtra("username"); String passowrd = intent.getStringExtra("password"); Toast.makeText(this, username, Toast.LENGTH_SHORT).show(); Toast.makeText(this, passowrd, Toast.LENGTH_SHORT).show(); Button btnFinish = (Button) findViewById(R.id.btnfinish); btnFinish.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { userNameEditText = (EditText) findViewById(R.id.newusername); passwordEditText = (EditText) findViewById(R.id.newpassword); Intent data = new Intent(); data.setData(Uri.parse("从SecondActivity返回的值")); Bundle bundle = new Bundle(); bundle.putString("newusername", userNameEditText.getText().toString()); bundle.putString("newPassword", passwordEditText.getText().toString()); data.putExtras(bundle); setResult(RESULT_OK, data); finish(); } }); } }
看看下面几行代码
getIntent方法用于获取启动这个Activity的Intent的对象
Intent intent = getIntent();
对象获取后就可以使用getStringExtra方法取得对象中保存的值
因为我们之前使用putExtra方法保存的是String对象,所以使用getStringExtra方法
如果保存的是Int对象,就可以使用getIntExtra方法,其他的以此类推。
String username = intent.getStringExtra("username");
String passowrd = intent.getStringExtra("password");
接着分析setData和putExtras方法
data.setData(Uri.parse("从SecondActivity返回的值"));
setData方法保存的是一个Uri对象,所以数据要先转换成Uri类型,
需要注意的是,setData方法一次只能保存一个数据,如果调用多次setData方法,
那么最后的数据就会覆盖之前的数据。
再来看Bundle的使用
Bundle bundle = new Bundle(); bundle.putString("newusername", userNameEditText.getText().toString()); bundle.putString("newPassword", passwordEditText.getText().toString()); data.putExtras(bundle);
Bundle对象主要用来保存键值对的数据,它有一系列的put方法,具体可以查看文档,不详细说明。
可以将Bundle对象看成是将要保存的数据打一个包,然后使用Intent的putExtras保存这个包裹然后发送出去。
数据准备好后,就可以使用setResult方法将数据返回
setResult(RESULT_OK, data);
我们返回MainActivity的onActivityResult方法
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUESTCODE) { if (resultCode == RESULT_OK) { // 获取从SecondActivity通过Bundle返回的值 Bundle extras = data.getExtras(); String newUserName = extras.getString("newusername"); String newPassword = extras.getString("newPassword"); nameText.setText(newUserName); passText.setText(newPassword); // 获取从SecondActivity通过setData返回的值 String strFromSec = data.getData().toString(); Toast.makeText(this, strFromSec, Toast.LENGTH_SHORT).show(); } } }
方法中的参数中有一个Intent类型的数据data,SecondActivity中的数据就是保存在这个参数中的。
如果数据返回成功,即resultCode等于RESULT_OK,我们就可以使用对应的get方法获取数据
如:
getExtras获取Bundle对象,getData获取使用setData设置的数据