Intent是一种运行时绑定(runtime binding)机制,它能在程序运行的过程中连接两个不同的组件。通过Intent,你的程序可以向Android表达某种请求或者意愿,Android会根据意愿的内容选择适当的组件来请求。在这些组件之间的通讯中,主要是由Intent协助完成的。Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。因此,Intent在这里起着一个媒体中介的作用,专门提供组件互相调用的相关信息,实现调用者与被调用者之间的解耦。
在Activity之间传递数据:在我们的实际应用开发中,不同的Activity之间进行切换的时候不可避免的进行数据传递。下面我们来介绍4种最常用的意图传递方式,这4种方式如下:
1、通过Intent传递数据
我们可以通过Intent类中的putExtra方法可以将简单的数据类型和序列化对象保存到Intent对象中,然后在目标的Activity中使用getXxx方法取出对应的数据。
Main.java
import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; public class Main extends Activity { private Button button; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 加载布局文件 button = (Button) this.findViewById(R.id.button);// button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Intent intent = new Intent(); // 在意图中传递数据 intent.putExtra("name", "张三"); intent.putExtra("age", 23); intent.putExtra("address", "北京"); intent.setClass(Main.this, OtherActivity.class); // 启动意图 startActivity(intent); } }); } }
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="测试使用Intent传递数据"></Button> </LinearLayout>
OtherActivity.java
import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.widget.TextView; public class OtherActivity extends Activity { private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.other); textView = (TextView) this.findViewById(R.id.msg); Intent intent = getIntent(); int age = intent.getIntExtra("age", 0); String name = intent.getStringExtra("name"); String address = intent.getStringExtra("address"); textView.setText("age--->>" + age + " " + "name-->>" + name + " " + "address->>" + address); } }
other.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/msg" android:layout_width="fill_parent" android:layout_height="fill_parent"> </TextView> </LinearLayout>
清单文件
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.laoluo.test" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.laoluo.test.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.laoluo.test.OtherActivity" android:label="@string/app_name" > </activity> </application> </manifest>
2、通过静态变量传递数据
使用Intent可以很方便在不同的Activity之间传递数据,这个也是官方推荐的方式,但是也有一定的局限性,就是Intent无法传递不能序列化的对象。我们可以使用静态变量来解决这个问题
Main.java
import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; public class Main extends Activity { /** Called when the activity is first created. */ private Button button; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); button = (Button) this.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub // 声明一个意图 Intent intent = new Intent(); intent.setClass(Main.this, OtherActivity.class); //在OtherActivity中先声明需要的静态变量,然后将值赋给OtherActivity中的静态变量 OtherActivity.age = 23; OtherActivity.name = "jack"; startActivity(intent); } }); } }
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:id="@+id/button" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="使用静态变量传递数据" /> </LinearLayout>
OtherActivity.java
package com.laoluo.test; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class OtherActivity extends Activity { private TextView textView; public static String name; public static int age; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.other); textView = (TextView)this.findViewById(R.id.msg); textView.setText("-name->>"+name+" "+"-age-->>"+age); } }
other.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/msg" android:layout_width="fill_parent" android:layout_height="fill_parent"> </TextView> </LinearLayout>
清单文件
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.laoluo.test" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.laoluo.test.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.laoluo.test.OtherActivity" android:label="@string/app_name" > </activity> </application> </manifest>
3、通过剪切板传递数据
在Activity之间数据传递还可以利用一些技巧,不管是Windows还是Linux操作系统,都会支持一种叫剪切板的技术,也就是某一个程序将一些数据复制到剪切板上,然后其他的任何程序都可以从剪切板中获取数据。
Main.java
import android.app.Activity; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.text.ClipboardManager; import android.view.View; import android.widget.Button; public class Main extends Activity { private Button button; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); button = (Button) this.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 从android系统中调用剪切板的服务 ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); String name = "jack"; clipboardManager.setText(name);//将数据设置到剪切板中 Intent intent = new Intent(Main.this, OtherActivity.class); startActivity(intent); } }); } }
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:text="使用剪切板传递数据" android:id="@+id/button" android:layout_width="fill_parent" android:layout_height="wrap_content"> </Button> </LinearLayout>
OtherActivity.java
import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.text.ClipboardManager; import android.widget.TextView; public class OtherActivity extends Activity { private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.other); textView = (TextView) this.findViewById(R.id.msg); ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); String msgString = clipboardManager.getText().toString();//取出剪切板中的内容 textView.setText(msgString); } }
other.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/msg" android:layout_width="fill_parent" android:layout_height="fill_parent"> </TextView> </LinearLayout>
清单文件
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.laoluo.test" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.laoluo.test.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.laoluo.test.OtherActivity" android:label="@string/app_name" > </activity> </application> </manifest>
该方法还可以用于传递一些比较复杂的数据,比如对象(清单文件和布局文件都一样)
MyData.java(将该对象作为数据在两个Activity之间传递)
import java.io.Serializable; public class MyData implements Serializable { //这里最好给该对象设置一个id:private static final long serialVersionUID = 1L; private String name; private int age; public MyData(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "MyData [name=" + name + ", age=" + age + "]"; } }
Main.java
import java.io.ByteArrayOutputStream; import java.io.ObjectOutputStream; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.text.ClipboardManager; import android.util.Base64; import android.view.View; import android.widget.Button; public class Main extends Activity { private Button button; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); button = (Button) this.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { MyData myData = new MyData("jack", 23); //将对象转换成字符串 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); String base64String = ""; try { ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); objectOutputStream.writeObject(myData); base64String = Base64.encodeToString(byteArrayOutputStream.toByteArray(), Base64.DEFAULT); objectOutputStream.close(); } catch (Exception e) { } ClipboardManager clipboardManager = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE); clipboardManager.setText(base64String); Intent intent =new Intent(Main.this,OtherActivity.class); startActivity(intent); } }); } }
OtherActivity.java
import java.io.ByteArrayInputStream; import java.io.ObjectInputStream; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.text.ClipboardManager; import android.util.Base64; import android.widget.TextView; public class OtherActivity extends Activity { private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.other); textView = (TextView) this.findViewById(R.id.msg); ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); String msgString = clipboardManager.getText().toString();//取出剪切板中的内容 byte[] base64_byte = Base64.decode(msgString, Base64.DEFAULT); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(base64_byte); try { ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); MyData myData = (MyData) objectInputStream.readObject(); textView.setText(myData.toString()); } catch (Exception e) { } } }
4、通过全局变量传递数据
在Activity之间数据传递中还有一种比较实用的方式,就是全局对象,实用J2EE的读者来说都知道Java Web的四个作用域,这四个作用域从小到大分别是Page、Request、Session和Application,其中Application域在应用程序的任何地方都可以使用和访问,除非是Web服务器停止,Android中的全局对象非常类似于Java Web中的Application域,除非是Android应用程序清除内存,否则全局对象将一直可以访问。
Main.java
import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; public class Main extends Activity { private Button button; private MyApp myApp; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); button = (Button)this.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { myApp = (MyApp)getApplication(); myApp.setName("jack");//修改之后的名称 Intent intent = new Intent(Main.this,OtherActivity.class); startActivity(intent); } }); } }
main.xml(同上一个实例一样)
OtherActivity.java
import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class OtherActivity extends Activity { private MyApp myApp; private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.other); textView = (TextView)this.findViewById(R.id.msg); myApp = (MyApp)getApplication(); textView.setText("-appname-->>"+myApp.getName()); } }
MyApp.java
import android.app.Application; public class MyApp extends Application { public String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public void onCreate() { super.onCreate(); setName("张三"); } }
other.xml (同上一个实例一样)
清单文件 (该方法清单文件上的配置有点区别,除了注册一个Activity之外,还要在application标签内标注全局应用, android:name=".MyApp"这个app的名称要跟全局应用的名称一致)
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.laoluo.test" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <application android:name=".MyApp" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.laoluo.test.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.laoluo.test.OtherActivity" android:label="@string/app_name" > </activity> </application> </manifest>
从Activity中返回数据
在实际的应用中,我们不仅仅要向Activity传递数据,而且要从Activity中返回数据,虽然返回数据和传递数据类似,也可以采用前面4种方法,但是一般建议采用Intent对象的方式来返回数据,使用这种方式返回数据,需要使用startActivityForResult方法来显示Activity。
Main.java
import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; public class Main extends Activity { private Button button; private final static int REQUESTCODE = 1; //返回的结果码 private EditText one,two,result; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); button = (Button) this.findViewById(R.id.button); one = (EditText)this.findViewById(R.id.one); two = (EditText)this.findViewById(R.id.two); result = (EditText)this.findViewById(R.id.result); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int a = Integer.parseInt(one.getText().toString()); int b = Integer.parseInt(two.getText().toString()); Intent intent = new Intent(Main.this, OtherActivity.class); intent.putExtra("a", a); intent.putExtra("b", b); //启动Intent startActivityForResult(intent, REQUESTCODE);//启动意图的另一种方法,这种方法可以返回结果, } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(resultCode==2){ if(requestCode==REQUESTCODE){ int three = data.getIntExtra("three", 0); result.setText(String.valueOf(three)); } } } }
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/one" android:layout_width="80dp" android:layout_height="wrap_content"> </EditText> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=" + "> </TextView> <EditText android:id="@+id/two" android:layout_width="80dp" android:layout_height="wrap_content"> </EditText> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=" = "> </TextView> <EditText android:id="@+id/result" android:layout_width="80dp" android:layout_height="wrap_content"> </EditText> </LinearLayout> <Button android:id="@+id/button" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="计算结果"> </Button> </LinearLayout>
OtherActivity.java
import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class OtherActivity extends Activity { private Button button; private TextView textView; private EditText editText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.other); button = (Button)this.findViewById(R.id.button2); textView = (TextView)this.findViewById(R.id.msg); editText = (EditText)this.findViewById(R.id.three); Intent intent = getIntent(); int a = intent.getIntExtra("a", 0); int b = intent.getIntExtra("b", 0); textView.setText(a+" + "+b+" = "+" ? "); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); int three = Integer.parseInt(editText.getText().toString()); intent.putExtra("three", three); //通过Intent对象返回结果,setResult方法, setResult(2, intent); finish();//结束当前的Activity的生命周期。 } }); } }
other.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/msg" android:layout_width="match_parent" android:layout_height="wrap_content"> </TextView> <EditText android:id="@+id/three" android:layout_width="match_parent" android:layout_height="wrap_content"> </EditText> </LinearLayout> <Button android:id="@+id/button2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="返回结果"> </Button> </LinearLayout>