【Android 开发】 : Activity之间传递数据的几种方式

在Android开发中,我们通常需要在不同的Activity之间传递数据,下面我们就来总结一下在Activity之间数据传递的几种方式。

1. 使用Intent来传递数据

Intent表示意图,很多时候我们都会利用Android的Intent来在各个Activity之间传递数据,这也是Android比较官方的一种数据传递的方式

需求1:从一个Activity(IntentDemo)跳转到另外一个Activity(Other),其中利用Intent来传递数据

程序Demo如下:

IntentDemo.java

[java]  view plain copy
  1. package com.android.intentdemo;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.view.View;  
  7. import android.widget.Button;  
  8.   
  9. public class IntentDemo extends Activity {  
  10.   
  11.     private Button button;  
  12.   
  13.     @Override  
  14.     public void onCreate(Bundle savedInstanceState) {  
  15.         super.onCreate(savedInstanceState);  
  16.         setContentView(R.layout.main);  
  17.         initComponent();  
  18.         button.setOnClickListener(new View.OnClickListener() {  
  19.             @Override  
  20.             public void onClick(View v) {  
  21.                 Intent intent = new Intent(IntentDemo.this, Other.class);  
  22.                 // 在Intent中传递数据  
  23.                 intent.putExtra("name""AHuier");  
  24.                 intent.putExtra("age"22);  
  25.                 intent.putExtra("address""XiaMen");  
  26.                 // 启动Intent  
  27.                 startActivity(intent);  
  28.             }  
  29.         });  
  30.     }  
  31.   
  32.     private void initComponent() {  
  33.         button = (Button) findViewById(R.id.button);  
  34.   
  35.     }  
  36. }  

other.java

[java]  view plain copy
  1. package com.android.intentdemo;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.widget.TextView;  
  7.   
  8. public class Other extends Activity {  
  9.   
  10.     private TextView textView;  
  11.   
  12.     @Override  
  13.     protected void onCreate(Bundle savedInstanceState) {  
  14.         // TODO Auto-generated method stub  
  15.         super.onCreate(savedInstanceState);  
  16.         setContentView(R.layout.other);  
  17.         initComponent();  
  18.   
  19.         Intent intent = getIntent();  
  20.         int age = intent.getIntExtra("age"0);  
  21.         String name = intent.getStringExtra("name");  
  22.         String address = intent.getStringExtra("address");  
  23.   
  24.         textView.setText("My age is " + age + "\n" + "My name is " + name + "\n" + "My address "  
  25.                 + address);  
  26.     }  
  27.   
  28.     private void initComponent() {  
  29.   
  30.         textView = (TextView) findViewById(R.id.msg);  
  31.     }  
  32. }  

  ——>

2. 在Activity之间使用静态变量传递数据

在上例中使用Intent可以很方便的在不同的Activity之间传递数据,这个也是官方推荐的方式,但是也有一定的局限性,就是Intent无法传递不能序列化的对象。我们可以使用静态变量来解决这个问题。

需求1:从一个Activity(IntentDemo)跳转到另外一个Activity(Other),其中利用静态变量来传递数据

程序Demo:

IntentDemo.java

[java]  view plain copy
  1. Intent intent = new Intent();  
  2. intent.setClass(IntentDemo.this, Other.class);  
  3. Other.age = 22;  
  4. Other.name = "AHuier";  
  5. Other.address = "XiaMen";  
  6. startActivity(intent);  

Other.java
[java]  view plain copy
  1. private TextView textView;  
  2. public static int age;  
  3. public static String name;  
  4. public static String address;  
  5.   
  6. @Override  
  7. protected void onCreate(Bundle savedInstanceState) {  
  8.     // TODO Auto-generated method stub  
  9.     super.onCreate(savedInstanceState);  
  10.     setContentView(R.layout.other);  
  11.     initComponent();  
  12.     textView.setText("My age is " + age + "\n" + "My name is " + name + "\n" + "My address "  
  13.             + address);  
  14. }  
 ——>

3. 通剪切板传递数据

   在Activity之间数据传递还可以利用一些技巧,不管是Windows还是Linux操作系统,都会支持一种剪切板的技术,也就是一个程序将一些数据复制到剪切板上,然后其他的任何程序都可以从剪切板中获取数据。

1) 利用剪切板传递普通的数据,如字符串

   需求1:从一个Activity(IntentDemo)跳转到另外一个Activity(Other),通过剪切板传递数据

   程序Demo:

IntentDemo.java

[java]  view plain copy
  1. ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);  
  2. String name = "AHuier";  
  3. clipboardManager.setText(name);  
  4. Intent intent = new Intent(IntentDemo.this, Other.class);  
  5. startActivity(intent);  
Other.java

[java]  view plain copy
  1. ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);  
  2. String msgString = clipboardManager.getText().toString();  
  3. textView.setText(msgString);  

 ——> 


1) 利用剪切板传递复杂的数据,如对象

需求1:从一个Activity(IntentDemo)跳转到另外一个Activity(Other),通过剪切板传递数据

新建一个MyData.java

[java]  view plain copy
  1. package com.android.intentdemo;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. public class MyData implements Serializable {  
  6.   
  7.     private String name;  
  8.     private int age;  
  9.   
  10.     public MyData(String name, int age) {  
  11.         super();  
  12.         this.name = name;  
  13.         this.age = age;  
  14.     }  
  15.   
  16.     // 提供一个toString()方法  
  17.     @Override  
  18.     public String toString() {  
  19.         return "MyData [name=" + name + ", age=" + age + "]";  
  20.     }  
  21.   
  22.     public String getName() {  
  23.         return name;  
  24.     }  
  25.   
  26.     public void setName(String name) {  
  27.         this.name = name;  
  28.     }  
  29.   
  30.     public int getAge() {  
  31.         return age;  
  32.     }  
  33.   
  34.     public void setAge(int age) {  
  35.         this.age = age;  
  36.     }  
  37.   
  38. }  
IntentDemo.java
[java]  view plain copy
  1. MyData myData = new MyData("AHuier"22);               
  2. //将对象转换成字符串  
  3. ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();  
  4. String base64String = "";  
  5. try {  
  6.     ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);  
  7.     objectOutputStream.writeObject(myData);  
  8. //使用Android中提供的 Base64 工具类,这个类主要是用来对对象进行压缩也解码的过程,使用默认方式  
  9.     base64String = Base64.encodeToString(byteArrayOutputStream.toByteArray(), Base64.DEFAULT);  
  10.     objectOutputStream.close();  
  11. catch (Exception e) {  
  12.     // TODO: handle exception  
  13. }  
  14. ClipboardManager clipboardManager = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);  
  15. clipboardManager.setText(base64String);  
  16. Intent intent = new Intent(IntentDemo.this, Other.class);  
  17. startActivity(intent);  

Other.java

[java]  view plain copy
  1.      ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);  
  2.      String msgString = clipboardManager.getText().toString();  
  3.        
  4. //将字符串 msgString 还原为对象  
  5.      byte[] base64_byte = Base64.decode(msgString, Base64.DEFAULT);  
  6.      ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(base64_byte);  
  7.      try {  
  8.          ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);  
  9.          MyData myData = (MyData)objectInputStream.readObject();  
  10.          textView.setText(myData.toString());  
  11.      } catch (Exception e) {  
  12.          // TODO: handle exception  
  13.      }  

 ——>

4.Intent中使用全局变量来传递数据

需求1:从一个Activity(Main)跳转到另外一个Activity(Other),通过全局变量来传递数据

Main.java

[java]  view plain copy
  1. private Button button;  
  2. private MyApp myApp;  
  3.  ...  
  4. myApp = (MyApp)getApplication();  
  5. myApp.setName("kunhuixu"); //修改之后的名称  
  6. Intent intent = new Intent(Main.this, Other.class);  
  7. startActivity(intent);  

Other.java

[java]  view plain copy
  1. private MyApp myApp;  
  2. private TextView textView;  
  3.  ...  
  4. myApp = (MyApp)getApplication();  
  5. textView.setText("--- The app name ---" + myApp.getName());  

MyApp.java

[java]  view plain copy
  1. package com.android.intentglobal;  
  2.   
  3. import android.app.Application;  
  4.   
  5. /* 
  6.  * 查看Android官方文档。 
  7.  * Application 是所有那些需要维护全局application状态的基类。你可以提供你自己的实现机制通过在在AndroidManifest.xml中提供你自己的需要声明 
  8.  * 的标记你自己的标签。 
  9.  * onCreate()方法是在应用程序启动的时候被回调的。 
  10.  */  
  11. public class MyApp extends Application {  
  12.      
  13.     public String name;  
  14.   
  15.     public String getName() {  
  16.         return name;  
  17.     }  
  18.   
  19.     public void setName(String name) {  
  20.         this.name = name;  
  21.     }  
  22.       
  23.     @Override  
  24.     public void onCreate() {  
  25.         // TODO Auto-generated method stub  
  26.         super.onCreate();  
  27.         setName("AHuier");  
  28.     }  
  29. }  

Andr oidManifest.xml

[html]  view plain copy
  1. <application  
  2.     android:name=".MyApp"  
  3.     android:icon="@drawable/ic_launcher"  
  4.     android:label="@string/app_name" >  
  5.     <activity  
  6.         android:name="com.android.intentglobal.Main"  
  7.         android:label="@string/app_name" >  
  8.         <intent-filter>  
  9.             <action android:name="android.intent.action.MAIN" />  
  10.   
  11.             <category android:name="android.intent.category.LAUNCHER" />  
  12.         </intent-filter>  
  13.     </activity>  
  14.     <activity android:name="com.android.intentglobal.Other"></activity>  
  15. </application>  

[注意]:使用 android:name=".MyApp" 来 指定全局变量名称。

 ——> 

http://blog.csdn.net/ahuier/article/details/8953017

【补充】

3. 不同Activity之间的数据传递

Bundle对象的实现

范例说明

在上一个范例里,介绍了如何在Activity中调用另一个Activity,但若需要在调用另外一个Activity的同时传递数据,那么就需要利用android.os.Bundle对象封装数据的能力,将欲传递的数据或参数,通过Bundle来传递不同Intent之间的数据。

本范例的设计为一个简易表单的范例,在Activity1中收集User输入的数据,在离开Activity1的同时,将User选择的结果传递至下一个Activity2,以一个简单BMI"标准体重计算器"示范如何传递数据到下一个Activity里。

运行结果

 
(点击查看大图)图3-10  在两个Activity间做数据的传递
范例程序
  
  
  1. src/irdc.ex03_10/EX03_10.java

在第一个Activity1主程序中,定义了"性别"选项的RadioGroup以及输入身高的"EditText",并运用Intent及Bundle对象,在调用Activity2(EX03_10_1)时,同时将数据传入。关于EditText对象的使用在此仅供参考,详细的应用以及属性方法,将会在未来讨论控件时,再详细解说。

  
  
  1. package irdc.ex03_10;  
  2.  
  3. /* import相关class */ 
  4. import android.app.Activity;  
  5. import android.content.Intent;  
  6. import android.os.Bundle;  
  7. import android.view.View;  
  8. import android.widget.Button;  
  9. import android.widget.EditText;  
  10. import android.widget.RadioButton;  
  11.  
  12. public class EX03_10 extends Activity   
  13. {  
  14.   /** Called when the activity is first created. */ 
  15.   @Override 
  16.   public void onCreate(Bundle savedInstanceState)   
  17.   {  
  18.     super.onCreate(savedInstanceState);  
  19.     /* 载入main.xml Layout */ 
  20.     setContentView(R.layout.main);  
  21.       
  22.     /* 以findViewById()取得Button对象,并添加onClickListener */ 
  23.     Button b1 = (Button) findViewById(R.id.button1);  
  24.     b1.setOnClickListener(new Button.OnClickListener()  
  25.     {  
  26.       public void onClick(View v)  
  27.       {  
  28.         /*取得输入的身高*/ 
  29.         EditText et = (EditText) findViewById(R.id.height);  
  30.         double height=Double.parseDouble(et.getText().toString());  
  31.         /*取得选择的性别*/ 
  32.         String sex="";  
  33.         RadioButton rb1 = (RadioButton) findViewById(R.id.sex1);  
  34.         if(rb1.isChecked())  
  35.         {  
  36.           sex="M";  
  37.         }  
  38.         else 
  39.         {  
  40.           sex="F";  
  41.         }  
  42.         /*new一个Intent对象,并指定class*/ 
  43.         Intent intent = new Intent();  
  44.         intent.setClass(EX03_10.this,EX03_10_1.class);  
  45.           
  46.         /*new一个Bundle对象,并将要传递的数据传入*/ 
  47.         Bundle bundle = new Bundle();  
  48.         bundle.putDouble("height",height);  
  49.         bundle.putString("sex",sex);  
  50.         
  51.         /*将Bundle对象assign给Intent*/ 
  52.         intent.putExtras(bundle);  
  53.         
  54.         /*调用Activity EX03_10_1*/ 
  55.         startActivity(intent);  
  56.       }  
  57.     });  
  58.   }  

src/irdc.ex03_10/EX03_10_1.java

那么,在Activity2(EX03_10_1)要如何接收来自Activity1(EX03_10)传递来的数据呢?试想,在Activity1是以Bundle封装对象,自然在Activity2亦是以Bundle的方式解开封装的数据;程序中以getIntent().getExtras() 方法取得随着Bundle对象传递过来的性别与身高,经过计算之后,显示在屏幕上。

  
  
  1. package irdc.ex03_10;  
  2.  
  3. /* import相关class */ 
  4. import java.text.DecimalFormat;  
  5. import java.text.NumberFormat;  
  6. import android.app.Activity;  
  7. import android.os.Bundle;  
  8. import android.widget.TextView;  
  9.  
  10. public class EX03_10_1 extends Activity   
  11. {  
  12.   /** Called when the activity is first created. */ 
  13.   @Override 
  14.   public void onCreate(Bundle savedInstanceState)  
  15.   {  
  16.     super.onCreate(savedInstanceState);  
  17.     /* 加载main.xml Layout */ 
  18.     setContentView(R.layout.myalyout);  
  19.       
  20.     /* 取得Intent中的Bundle对象 */ 
  21.     Bundle bunde = this.getIntent().getExtras();  
  22.       
  23.     /* 取得Bundle对象中的数据 */ 
  24.     String sex = bunde.getString("sex");  
  25.     double height = bunde.getDouble("height");  
  26.       
  27.     /* 判断性别 */ 
  28.     String sexText="";  
  29.     if(sex.equals("M"))  
  30.     {  
  31.       sexText="男性";  
  32.     }  
  33.     else 
  34.     {  
  35.       sexText="女性";  
  36.     }  
  37.       
  38.     /* 取得标准体重 */ 
  39.     String weight=this.getWeight(sex, height);  
  40.       
  41.     /* 设置输出文字 */ 
  42.     TextView tv1=(TextView) findViewById(R.id.text1);  
  43.     tv1.setText("你是一位"+sexText+"\n你的身高是" 
  44.                 +height+"厘米\n你的标准体重是"+weight+"公斤");  
  45.   }  
  46.     
  47.   /* 四舍五入的method */ 
  48.   private String format(double num)  
  49.   {  
  50.     NumberFormat formatter = new DecimalFormat("0.00");  
  51.     String s=formatter.format(num);  
  52.     return s;  
  53.   }  
  54.  
  55.   /* 以findViewById()取得Button对象,并添加onClickListener */    
  56.   private String getWeight(String sex,double height)  
  57.   {  
  58.     String weight="";  
  59.     if(sex.equals("M"))  
  60.     {  
  61.       weight=format((height-80)*0.7);  
  62.     }  
  63.     else 
  64.     {  
  65.       weight=format((height-70)*0.6);  
  66.     }    
  67.     return weight;  
  68.   }  

res/layout/mylayout.xml

mylayout.xml为(EX03_10_1)的Layout,定义了显示计算结果的TextView。

  
  
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <AbsoluteLayout  
  3.   android:layout_width="fill_parent" 
  4.   android:layout_height="fill_parent" 
  5.   xmlns:android="http://schemas.android.com/apk/res/android" 
  6. >  
  7.   <TextView  
  8.     android:id="@+id/text1" 
  9.     android:layout_width="wrap_content" 
  10.     android:layout_height="wrap_content" 
  11.     android:textSize="20sp" 
  12.     android:layout_x="50px" 
  13.     android:layout_y="72px" 
  14.   >  
  15.   </TextView>  
  16. </AbsoluteLayout> 

AndroidManifest.xml

由于本范例中有两个Activity,所以文件中必须有两个activity的声明,否则系统将无法运行,请看以下的描述。

  
  
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest  
  3.   xmlns:android="http://schemas.android.com/apk/res/android" 
  4.   package="irdc.ex03_10" 
  5.   android:versionCode="1" 
  6.   android:versionName="1.0.0">  
  7.   <application  
  8.     android:icon="@drawable/icon"   
  9.     android:label="@string/app_name">  
  10.     <activity  
  11.       android:name=".EX03_10" 
  12.       android:label="@string/app_name">  
  13.       <intent-filter>  
  14.         <action android:name="android.intent.action.MAIN" />  
  15.         <category android:name="android.intent.category.LAUNCHER" />  
  16.       </intent-filter>  
  17.     </activity>  
  18.     <activity android:name="EX03_10_1"></activity>  
  19.   </application>  
  20. </manifest> 

扩展学习

Bundle对象针对了不同的数据类型提供了许多的方法,例如,此范例中传递String类型的数据,使用的方法为Bundle.putString(stringName,stringValue):

  
  
  1. bundle.putDouble("sex",sex); 

而要传递Double类型的数据,使用的方法为Bundle.putDouble(doubleName,doubleValue),如下:

  
  
  1. bundle.putString("height",height); 

反之,若要由Bundle对象中取出数据,则使用Bundle.getString(stringName)、Bundle.getDouble(doubleName) 等相对应的方法即可。

除了上述简单的传递类型之外,尚有String[] 与ArrayList<String> 等封装的方式可供使用

参考。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值