学习安卓编程权威指南第五章的时候自己写了个简单的Demo来加深理解两个Activity互相传递数据的问题,然后将自己的学习笔记贴上来,如有错误还请指正。
IntentActivityDemo学习笔记
题目:ActivityA登录界面(用户名、密码、登陆按钮),ActivityB(Edit,返回按键:SubmitButton)。A界面输入用户名和密码传到B中,B验证用户输入的用户名和密码,如果错误就返回A,并用Toast 显示用户名和密码错误;如果正确,就在第二个 activity中显示一个Edit,用户输入后点击SubmitButton回到A,用 Toast 提示用户计算结束。
这里使用的方法是显式的intent。
一个activity启动另一个activity最简单的方式是使用以下startActivity方法:
public void startActivity(Intent intent)
调用请求发送给了操作系统的ActivityManager,ActivityManager负责创建activityB实例并调用其onCreate(...)方法,示意图如下:
intent是一种多用途通信工具。 Intent类提供了多个构造方法,以满足不同的使用需求。
public Intent(Context packageContext, Class<?> cls)
传入该方法的Class类型参数告诉ActivityManager应该启动哪个activity; Context参数告诉ActivityManager在哪里可以找到它。原理如图:
如果是简单的启动一个Activity这个方法就可以了,我们这里需要传递username,password到ActivityB中,需要两个Activity之间相互传递数据。我们使用startActivityForResult函数,在这之前,先说一下intent extra。之后再说startActivityForResult(0x02)
Extra也是一种键值结构,要将extra数据信息添加给intent,需要调用Intent.putExtra(...)方法。确切地说,是调用
public Intent putExtra(String name, boolean value)
Intent.putExtra(...)方法形式多变。不变的是,它总是有两个参数。一个参数是固定为String类型的键,另一个参数值可以是多种数据类型。该方法返回intent自身,因此,需要时可进行链式调用。
相对应的还有获得extra的信息的方法:
要从extra获取数据,会用到如下方法:
public boolean getBooleanExtra(String name, boolean defaultValue)
第一个参数是extra的名字。 getBooleanExtra(...)方法的第二个参数是指定默认值(默认答案),它在无法获得有效键值时使用,当无法获得有效值的时候,truefalse会根据这个函数的设置而确定。
接下来我们开始写简单的代码了。
0x01
首先,A中输入username、password点击loginButton,所以我们在loginButton添加事件监听,并且将我们输入的username和password传到B中。
Activity可能启动自不同的地方,我们应该为activity获取和使用的extra定义键。 并且使用包名修饰extra数据信息,可以避免来自不同应用的extra间发生命名冲突, 如代码所示:
//login username 键值
private static
final String EXTRA_LOGIN_USERNAME =
"com.example.zc.practice_geoquiz.login_usename";
//login password
键值
private static
final String EXTRA_LOGIN_PASSWORD =
"com.example.zc.practice_geoquiz.login_password";
现在,可以返回到QuizActivity并将extra附加到intent上。不过我们有个更好的实现方法。
对于ActivityB处理extra信息的实现细节,ActivityA和应用的其他代码无需知道。因而,我们可转而在newIntent(...)方法中封装这些逻辑。
在ActivityB中,创建newIntent(...)方法,如代码所示。
public static Intent newIntent(
Context packageContext, String username, String password)
{
Intent i = new Intent(packageContext, ActivityB.class);
//username 放到EXTRA_LOGIN_USERNAME 键值中
i.putExtra(EXTRA_LOGIN_USERNAME, username);
i.putExtra(EXTRA_LOGIN_PASSWORD, password);
return i;
}
之后会上源代码,源代码中的注释会详细一些。
好的这里调试一下看是否得到:
这里我设置的正确的是123 123
故意输错 22 22:
好的这里得到了。
0x02
我们接着来,我们在B中要判断username和password正确与否并且要将这个验证结果返还给A。
因为我们需要从B中获得数据到A中所以我们之前的启动Activity使用的是startActivityForResult。
public void startActivityForResult(Intent intent, int requestCode)
该方法的第一个参数同前述的intent。第二个参数是请求代码。 请求代码是先发送给子activity,然后再返回给父activity的用户定义整数值。当一个activity启动多个不同类型的子activity,
且需要判断区分消息回馈方时,通常会用到该请求代码。虽然QuizActivity只启动一种类型的子activity,但为应对未来的需求变化,现在就应设置请求代码常量。
代码如下;
/*REQUEST_LOGININFO
onActivityResult(int requestCode, int resultCode, Intent intent)
中的requestCode
*/
startActivityForResult(v1, REQUEST_LOGININFO);
0x03
设置结果值
因为B要告诉A你给我传过来的那些username和password对不对,所以我们这里同样也是使用键值EXTRA_IS_LOGIN,然后使用setResult来设置结果值反给A,A自动走onActivityResult(后面我们要自己重写),注意B这里后面必须调用finish()函数或者是back动作后,才会到A的onActivityResult中。
代码如下:
private void IsLogIn(boolean IsLogIn)
{
Intent v1 = new Intent();
v1.putExtra(EXTRA_IS_LOGIN, IsLogIn);
setResult(RESULT_OK, v1);
/*
第二个页面finish()动作或者back动作后,会回调第一个页面的onActivityResult()方法
*/
finish();
}
调试一下,就能否到A的onActivityResult中:
然后
好的走到了,接下来就是来看看你给我的是什么信息。
在B中,代码如下:
public static boolean IsInfor(Intent intent)
{
return intent.getBooleanExtra(EXTRA_IS_LOGIN, true);
/*
第二参数有影响,如果没有被设置就是默认值!!!!
这个没有被设置的情况就是 B中的edit给A的情况
*/
}
然后A中,代码如下:
mIsLoginSuccess = ActivityB.IsInfor(intent);
if(mIsLoginSuccess == false)
{
Toast.makeText(this, "用户名和密码错误", Toast.LENGTH_SHORT)
.show();
}
调试一下:
1) 输入 22 22 错误的情况:
2) 输入123 123 正确进入
到这里我们的第一步,登录界面的东西就写完了也就是A到B 可以了,接下来B到A:
0x04
在submitbutton点击事件监听中,代码如下:
mResultText = (EditText) findViewById(R.id.result_text);
existedText = mResultText.getText().toString();
Intent v1 = new Intent();
v1.putExtra(EXTRA_EDITVIEW_RESULT, existedText);
setResult(RESULT_OK, v1);
/*
第二个页面finish()动作或者back动作后,会回调第一个页面的onActivityResult()方法
*/
finish();
一样也是使用putExtra把数据设置到键值中,使用setResult和finish到A中调用onActivityResult。
A中代码如下:
if(mIsLoginSuccess == false)
{
Toast.makeText(this, "用户名和密码错误", Toast.LENGTH_SHORT)
.show();
}
else
{
Result = ActivityB.GetResult(intent);
Toast.makeText(this, Result, Toast.LENGTH_SHORT)
.show();
}
自定义方法GetResult:
public static String GetResult(Intent intent)
{
return intent.getStringExtra(EXTRA_EDITVIEW_RESULT);
}
调试:
B:
A:
成功。
0x05
之前getBooleanExtra方法中第二参数一开始不了解,后来通过调试理解什么意思:
正确的代码:
这里我们将第二参数设置为false:
对于username和password错误的情况没有问题:
对于B给A传数据的时候,由于有这一句:
因为第二次的条件下,我们的username,password是正确的,所以不会走到这个里面:
所以,我们B给A数据的时候会走默认:
所以会返回false,进入:
示意图如下:
0x01:
密码正确,用户名正确
0x02:
点击submit
0x03:
所以可以理解那个默认的意思了。
源代码:
链接:http://pan.baidu.com/s/1bplhlXt 密码:x0x2
1 // IntentActivityDemo.java 2 package com.example.zc.intentactivitydemo; 3 4 import android.app.Activity; 5 import android.content.Intent; 6 import android.support.v7.app.AppCompatActivity; 7 import android.os.Bundle; 8 import android.view.View; 9 import android.widget.Button; 10 import android.widget.EditText; 11 import android.widget.TextView; 12 import android.widget.Toast; 13 14 public class IntentActivityDemo extends AppCompatActivity { 15 16 private EditText mUserName; 17 private String username = ""; 18 private EditText mPassWord; 19 private String password = ""; 20 21 private Button mLoginButton; 22 23 private boolean mIsLoginSuccess; 24 25 /* 26 onActivityResult(int requestCode, int resultCode, Intent intent) 27 中的requestCode 28 */ 29 private static final int REQUEST_LOGININFO = 0; 30 31 private String Result; 32 33 34 @Override 35 protected void onCreate(Bundle savedInstanceState) 36 { 37 super.onCreate(savedInstanceState); 38 setContentView(R.layout.activity_intent_demo); 39 40 mUserName = (EditText) findViewById(R.id.username); 41 //username = mUserName.getText().toString(); 42 43 mPassWord = (EditText) findViewById(R.id.password); 44 //password = mPassWord.getText().toString(); 45 46 47 //login 48 mLoginButton = (Button) findViewById(R.id.login);//引用已生成的组件 49 mLoginButton.setOnClickListener( 50 new View.OnClickListener() { 51 @Override 52 public void onClick(View v) 53 { 54 username = mUserName.getText().toString(); 55 password = mPassWord.getText().toString(); 56 57 String UserNameToCalc = username; 58 String PassWordToCalc = password; 59 60 Intent v1 = ActivityB.newIntent( 61 IntentActivityDemo.this,UserNameToCalc,PassWordToCalc); 62 63 64 /*REQUEST_LOGININFO 65 onActivityResult(int requestCode, int resultCode, Intent intent) 66 中的requestCode 67 */ 68 startActivityForResult(v1, REQUEST_LOGININFO); 69 70 71 } 72 } 73 ); 74 75 } 76 77 /* 78 79 在第二个页面finish()动作或者back动作后,会回调第一个页面的onActivityResult()方法 80 81 新 增 一 个 成 员 变 量 保 存 CheatActivity 回 传 的 值 。 然 后 覆 盖 82 onActivityResult(...)方法获取它 83 */ 84 @Override 85 protected void onActivityResult(int requestCode, int resultCode, Intent intent) 86 { 87 if (resultCode != Activity.RESULT_OK) 88 { 89 return; 90 } 91 if (requestCode == REQUEST_LOGININFO) 92 { 93 if (intent == null) 94 { 95 return; 96 } 97 98 99 mIsLoginSuccess = ActivityB.IsInfor(intent); 100 101 if(mIsLoginSuccess == false) 102 { 103 Toast.makeText(this, "用户名和密码错误", Toast.LENGTH_SHORT) 104 .show(); 105 } 106 107 108 else 109 { 110 Result = ActivityB.GetResult(intent); 111 Toast.makeText(this, Result, Toast.LENGTH_SHORT) 112 .show(); 113 114 } 115 116 } 117 } 118 119 120 121 122 123 }
1 // ActivityB 2 package com.example.zc.intentactivitydemo; 3 4 import android.content.Context; 5 import android.content.Intent; 6 import android.support.v7.app.AppCompatActivity; 7 import android.os.Bundle; 8 import android.view.View; 9 import android.widget.Button; 10 import android.widget.EditText; 11 12 public class ActivityB extends AppCompatActivity 13 { 14 15 //login username 键值 16 private static final String EXTRA_LOGIN_USERNAME = 17 "com.example.zc.practice_geoquiz.login_usename"; 18 //login password 键值 19 private static final String EXTRA_LOGIN_PASSWORD = 20 "com.example.zc.practice_geoquiz.login_password"; 21 22 //登录信息正确与否 23 private static final String EXTRA_IS_LOGIN = 24 "com.example.zc.practice_geoquiz.is_login"; 25 26 27 //editview结果 28 private static final String EXTRA_EDITVIEW_RESULT = 29 "com.example.zc.practice_geoquiz.editview_result"; 30 31 private String mUsername = ""; 32 private String mPassword = ""; 33 34 private EditText mResultText; 35 36 /*** 已经输入的字符 ***/ 37 private String existedText = ""; 38 39 40 private Button mSubmitButton; 41 42 43 @Override 44 protected void onCreate(Bundle savedInstanceState) 45 { 46 super.onCreate(savedInstanceState); 47 setContentView(R.layout.activity_b); 48 49 //取出键值到mUsername... 50 mUsername = getIntent().getStringExtra(EXTRA_LOGIN_USERNAME); 51 mPassword = getIntent().getStringExtra(EXTRA_LOGIN_PASSWORD); 52 53 if(!mUsername.equals("123")) 54 { 55 if(!mPassword.equals("123")) 56 { 57 IsLogIn(false); 58 } 59 } 60 61 //返回第一个Activity 62 mSubmitButton = (Button) findViewById(R.id.submit); 63 mSubmitButton.setOnClickListener( 64 new View.OnClickListener() 65 { 66 @Override 67 public void onClick(View v) 68 { 69 mResultText = (EditText) findViewById(R.id.result_text); 70 existedText = mResultText.getText().toString(); 71 72 Intent v1 = new Intent(); 73 v1.putExtra(EXTRA_EDITVIEW_RESULT, existedText); 74 setResult(RESULT_OK, v1); 75 /* 76 第二个页面finish()动作或者back动作后,会回调第一个页面的onActivityResult()方法 77 */ 78 finish(); 79 80 81 } 82 } 83 ); 84 85 86 } 87 88 89 90 public static Intent newIntent( 91 Context packageContext, String username, String password) 92 { 93 Intent i = new Intent(packageContext, ActivityB.class); 94 95 //username 放到EXTRA_LOGIN_USERNAME 键值中 96 i.putExtra(EXTRA_LOGIN_USERNAME, username); 97 i.putExtra(EXTRA_LOGIN_PASSWORD, password); 98 99 100 101 return i; 102 103 104 /* 105 Intent.putExtra(...)方法形式多变。不变的是,它总是有两个参数。 106 一个参数是固定为String类型的键,另一个参数值可以是多种数据类型。该方法返回intent自身, 107 因此,需要时可进行链式调用。 108 */ 109 /* 110 要从extra获取数据,会用到如下方法:(一种方法) 111 public boolean getBooleanExtra(String name, boolean defaultValue) 112 第一个参数是extra的名字。 getBooleanExtra(...)方法的第二个参数是指定默认值(默认 113 答案),它在无法获得有效键值时使用。 114 */ 115 116 117 } 118 119 private void IsLogIn(boolean IsLogIn) 120 { 121 Intent v1 = new Intent(); 122 v1.putExtra(EXTRA_IS_LOGIN, IsLogIn); 123 setResult(RESULT_OK, v1); 124 125 /* 126 第二个页面finish()动作或者back动作后,会回调第一个页面的onActivityResult()方法 127 */ 128 finish(); 129 } 130 131 132 public static boolean IsInfor(Intent intent) 133 { 134 return intent.getBooleanExtra(EXTRA_IS_LOGIN, false); 135 /* 136 第二参数有影响,如果没有被设置就是默认值!!!! 137 这个没有被设置的情况就是 B中的edit给A的情况 138 */ 139 } 140 141 142 public static String GetResult(Intent intent) 143 { 144 return intent.getStringExtra(EXTRA_EDITVIEW_RESULT); 145 } 146 147 148 }