从Intent的定义可知,Intent除了定位目标组件外,另外一个职责就是传递数据信息。

1、传递基本数据

Intent间传递数据一般有两种方法:一种是通过data属性,另一种是通过extra属性。

data属性是一种URL,它可以是指向我们熟悉的HTTP,FTP网络地址,也可以指向ContentProvider提供的资源,通过调用Intent的setData方法可以放入数据,相应地,调用getData方法可以取出数据。

例如:需要启动Android内置的浏览器:

 

Intent  intent = new Intent();

intent,setAction(Intent.ACTION_VIEW);

intent.setData(Uri.parse(http://www.google.com.hk));

startActivity(intent);

startActivity(intent);

由于data属性只能传递数据的URL地址,如果需要传递一些数据对象,则就需要利用extra了。

extra可以通过Intent的putExtra方法放入数据,方法putExtra的参数是一个Bundle对象,(所谓Bundle是专门用来在Android的应用组件之间传递数据的一种对象,它本质上是一个Map对象,可以将各种基本的数据类型的数据保存在Bundle类中进行打包传输)

例子:

调用ActicityOne的代码片段:

firstbtn.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				// 显式启动 Activity One
				Intent i = new Intent(getApplicationContext(),
						ActivityOne.class);
				Bundle bd = new Bundle();				bd.putString("username", "android");
				i.putExtra("attachment", bd);
				startActivity(i);
			}
		});

Acticity的代码:

package com.demo.intent;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

public class ActivityOne extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activityone);
		String tag = "ActivityOne onCreate..";
		Intent i = getIntent();
		Bundle b = i.getBundleExtra("attachment");
		Log.d(tag, b.getString("username"));
		Log.d(tag, "han been started ");
	}
}

从Intent获取信息的代码放在onCreate方法中,在通常情况下没有问题,但是存在隐患。

首先在默认情况下,当通过Intent获取一个Activity的时候,就算已经存在一个相同的正在运行的Activity,系统都会创建一个新的Activity实例并显示出来,为了不让Activity多次实例化,开发人员需要在AndroidManiFest.xml配置Activity的加载方式(launchMode)一实现单任务模式:

<activity  android:name="Activity"

android:launchmode="singleTask">

</activity>

launchMode为singleTask时候,通过Intent启动一个Activity,如果系统已经存在一个实例,系统就会将请求发送到这个实例上去,但这时,系统就不会再调用通常处理请求数据的onCrtate()方法,而是调用onNewIntent()方法。

最安全的方法便是在onCrtate和onNewInten方法中调用同一个处理数据的方法:

package com.demo.intent;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

public class ActivityOne extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		processExtraData();
		
	}
	protected  void onNewIntent(Intent intent){
		
		super.onNewIntent(intent);
		setIntent(intent);
		processExtraData();
	}
	
	private  void  processExtraData(){
		
		Intent intent =  getIntent();
		//在下面处理Intent附加数据
	}
}

2、复杂对象的传递

传递的复杂的自定义对象,利用Intent传递有两种方法:

一种是Bundle.putSerializable(Key,Object),另一种是BUundle.putParcelableArrayListExera(Key,Object),

Object的条件:一种是实现Serializable接口,而后者实现了Parcelable接口,在Android运行环境中推荐使用Parcelable接口,它不但可以利用Intent传递,还可以在远程方法调用使用。

实现Parcelable需要以下操作:

writeToParcel方法:该方法将类的数据写入外部提供的parcel中。

describeContents方法:返回内容描述信息的资源ID。

静态的Parcelable.Creator接口,本接口有两个方法:

createrFromParcel(Parcel in ):实现从parcel实例中创建出类的实例的功能。

new  Array(int  size)  :创建一个类型T,长度为size的数组。

演示:

实体类:   student.java

package com.demo.intent;

import java.util.HashMap;
import android.os.Parcel;
import android.os.Parcelable;

public class Student implements Parcelable {
	public Student() {
		name = "unknown";
		scores = null;
	}

	public HashMap<String, String> scores = new HashMap<String, String>();
	public String name;

	@Override
	public int describeContents() {
		return 0;
	}

	@Override
	public void writeToParcel(Parcel dest, int flags) {
		dest.writeMap(scores);
		dest.writeString(name);
	}

	public static final Parcelable.Creator<Student> CREATOR = new Parcelable.Creator<Student>() {
		@Override
		public Student createFromParcel(Parcel source) {
			Student p = new Student();
			p.scores = source.readHashMap(HashMap.class.getClassLoader());
			p.name = source.readString();
			return p;
		}

		@Override
		public Student[] newArray(int size) {
			// TODO Auto-generated method stub
			return new Student[size];
		}
	};
}

作为封装学生信息的实体类,它实现了Parcleable接口。

main.java

package com.demo.intent;

import java.util.ArrayList;
import java.util.HashMap;
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 {

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		Button firstbtn = (Button) findViewById(R.id.activity1);
		firstbtn.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				// 显式启动 Activity One
				Intent i = new Intent(getApplicationContext(),
						ActivityOne.class);
				Bundle bd = new Bundle();
				Student s = new Student();
				HashMap<String, String> sc = new HashMap<String, String>();
				sc.put("english", "98");
				sc.put("computer", "75");
				s.name = "tom";
				s.scores = sc;
				ArrayList<Student> al = new ArrayList<Student>();
				al.add(s);
				i.putParcelableArrayListExtra("attachment2", al);
				bd.putString("username", "android");
				i.putExtra("attachment", bd);
				startActivity(i);
			}
		});

	}
}

说明:首先创建一个student,然后将其放入ArrayList中,并调用putParceableArrayListExtra()方法将其加入Intent

activityone.java

 

package com.demo.intent;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

public class ActivityOne extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activityone);
		String tag = "ActivityOne onCreate..";
		Intent i = getIntent();
		Bundle b = i.getBundleExtra("attachment");
		Log.d(tag, b.getString("username"));
		Log.d(tag, "han been started ");
		ArrayList<Student> al = new ArrayList<Student>();
		al = i.getParcelableArrayListExtra("attachment2");
		if (al != null) {
			Student s = (Student) al.get(0);
			Log.i(tag, "---->" + s.name);
			Iterator iter = s.scores.entrySet().iterator();
			while (iter.hasNext()) {
				Map.Entry entry = (Map.Entry) iter.next();
				String key = (String) entry.getKey();
				String val = (String) entry.getValue();
				Log.i(tag, key.toString() + val.toString());
			}
		}

	}
}

说明:为获取传递过来的实现Parcleable接口的对象,首先调用getParcelableArrayListExtra方法获得一个ArrayList对象,然后从ArrayList中操作student对象即可。

 



package com.demo.intent;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

public class ActivityOne extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activityone);
		String tag = "ActivityOne onCreate..";
		Intent i = getIntent();
		Bundle b = i.getBundleExtra("attachment");
		Log.d(tag, b.getString("username"));
		Log.d(tag, "han been started ");
		ArrayList<Student> al = new ArrayList<Student>();
		al = i.getParcelableArrayListExtra("attachment2");
		if (al != null) {
			Student s = (Student) al.get(0);
			Log.i(tag, "---->" + s.name);
			Iterator iter = s.scores.entrySet().iterator();
			while (iter.hasNext()) {
				Map.Entry entry = (Map.Entry) iter.next();
				String key = (String) entry.getKey();
				String val = (String) entry.getValue();
				Log.i(tag, key.toString() + val.toString());
			}
		}

	}
}