对于Intent来说,我们之前也简单的接触到一些。它的作用也十分的明显,用于传递一些数据;其实,它还有另一个用途,描述你想要干的事情,是Android四大组件(Activity,Service,BroadcastReciver,ContentProvider)之间的纽带。
这两个关键的作用,我就带着大家一一进行讲解,方便大家的理解。
1.Activity之间传递数据:
a.传递基本数据类型/String
b.传递Bundle(底层实现是Map)
c.传递自定义对象(序列化)
Serializable和Parcelable接口都可以实现 对 对象的序列化和反序列化
Serializable接口是java提供的接口,它的序列化和反序列化是基于磁盘的,效率相对较低 (不可以跨进程通讯 )
Parcelable接口是Android提供的接口,它的序列化和反序列化是基于内存的,效率要比Serializable要高。推荐使用。(跨进程通讯)
注意:
Parcelable序列化的时候,write属性的顺序必须和read的顺序一致
简单的说,我们一般用到的在Activity之间传递数据无非就以上三种。接下来给大家看一下示例代码,方便大家的理解。(这里不再给出XML文件的代码,大家可以自行敲一下,因为只是一些简单的布局,就没有必要再浪费大家的时间)
(1)MainActivity.java
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Map;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
public class MainActivity extends Activity implements OnClickListener
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//事件监听
findViewById(R.id.button1).setOnClickListener(this);
findViewById(R.id.button2).setOnClickListener(this);
findViewById(R.id.button3).setOnClickListener(this);
findViewById(R.id.button4).setOnClickListener(this);
findViewById(R.id.button5).setOnClickListener(this);
findViewById(R.id.button6).setOnClickListener(this);
}
@Override
public void onClick(View v)
{
Intent intent = new Intent(this, SecondActivity.class);
switch (v.getId())
{
//基本数据类型/String
case R.id.button1:
//数据
/*
* 参一:类似于Map中的key,到跳转的界面后,通过此key将value取出来
*/
intent.putExtra("name", "张三");
intent.putExtra("age", 20);
break;
//传递Bundle
case R.id.button2:
/*
* Bundle:底层封装的是Map,对HashMap进一步封装,使用起来更加方便
*/
Bundle extras = new Bundle();
extras.putString("name", "李四");
extras.putInt("age", 18);
intent.putExtras(extras);
//传递数组
case R.id.button3:
intent.putExtra("animals", new String[]{"Dog","Cat","Pig"});
break;
//传递自定义对象(Person)Serializable
case R.id.button4:
intent.putExtra("person", new Person("小明", 12));
break;
//传递自定义对象(Student)Parcelable
case R.id.button5:
/*
* Serializable和Parcelable接口都可以实现 对 对象的序列化和反序列化
* Serializable接口是java提供的接口,它的序列化和反序列化是基于磁盘的,效率相对较低
* Parcelable接口是Android提供的接口,它的序列化和反序列化是基于内存的,效率要比Serializable要高。推荐使用。
*/
intent.putExtra("student", new Student("小亮", 15));
break;
case R.id.button6:
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student("小李", 20));
list.add(new Student("小邓", 22));
intent.putParcelableArrayListExtra("list", list);
break;
}
startActivity(intent);
}
}
//实现 Parcelable
class Student implements Parcelable
{
private String name;
private int age;
public Student(String name, int age)
{
super();
this.name = name;
this.age = age;
}
public int describeContents() {
return 0;
}
//将数据写入Parcel
public void writeToParcel(Parcel out, int flags) {
out.writeString(name);
out.writeInt(age);
}
public static final Parcelable.Creator<Student> CREATOR
= new Parcelable.Creator<Student>() {
public Student createFromParcel(Parcel in) {
return new Student(in);
}
public Student[] newArray(int size) {
return new Student[size];
}
};
//从Parcel读取数据
private Student(Parcel in) {
name = in.readString();
age = in.readInt();
}
@Override
public String toString()
{
return this.name+" "+this.age;
}
}
//Serializable:序列化接口 接口是在定义一种规范
class Person implements Serializable
{
private String name;
private int age;
public Person(String name, int age)
{
super();
this.name = name;
this.age = age;
}
@Override
public String toString()
{
return this.name+" "+this.age;
}
}
(2)SecondActivity.java
import java.util.ArrayList;
import java.util.Arrays;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
public class SecondActivity extends Activity
{
TextView mTvShow;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
mTvShow = (TextView) findViewById(R.id.tv_show);
//取上个界面传过来的数据
//哪个Intent启动的此Activity,这个方法返回的就是这个Intent
Intent intent=getIntent();
/*
* 传递基本数据类型
String name = intent.getStringExtra("name");
int age = intent.getIntExtra("age", 0);
mTvShow.setText("name:"+name+" age:"+age);*/
/*
* 传递Bundle数据
* Bundle bdl = intent.getExtras();
String name = bdl.getString("name");
int age = bdl.getInt("age");
mTvShow.setText("name:"+name+" age:"+age);*/
/*
* 传递数组数据
* String[] animals = intent.getStringArrayExtra("animals");
mTvShow.setText("animals:"+Arrays.toString(animals));*/
/*
* 传递对象数据 Serializable
* Person person=(Person) intent.getSerializableExtra("person");
mTvShow.setText("person:"+person.toString());*/
/*
* 传递对象数据 Parcelable
* Student student=intent.getParcelableExtra("student");
mTvShow.setText("person:"+student.toString());*/
//Parcelable类型的集合数据
ArrayList<Student> list = intent.getParcelableArrayListExtra("list");
mTvShow.setText("list:"+list.toString());
}
}
上面很多都是我自己打了注释的,大家在参考代码的时候,可以把注释放开。以上呢,就是我理解的传递数据的一些知识点的整理。
2.Intent隐式意图:
对于显式意图来说,大家理解起来肯定很容易,我贴一小段代码,大家看后就理解了:
a.显示意图:用于启当前应用中的其它组件
Intent intent = new Intent(this, Other1Activity.class);
startActivity(intent);
b.隐式意图:意图过滤器---可以用于同一个应用或者不同应用之间。可能这个概念大家不是很了解,那我现在带着大家慢慢的去看一下隐式意图到底是什么东东,其实在刚刚开始的时候,我对其理解也不是很透彻,但是看了一下网上的代码和书,也是逐渐明白了其原理。
接下来,我用我的大白话给大家讲述一下:
如果你有一个组件希望别的应用程序可以调用,你就应该给你这个组件配置一个intent-filter
<intent-filter>
<action android:name="com.tz.go1"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
intent-filter:包含两部分
1,目的【action】---->你要到哪里去
2,内容【category+data】----》去的路上要带什么 区分性的数据和内容性的数据
可以认为就在Action的基础上增加了过滤条件
I.action+category
默认category (android.intent.category.DEFAULT)必须配置,你也可以添加自己的。
II.action+category+data(增加了一个过滤条件)
<data
android:scheme="sun"
android:host="www.sun.com"
android:path="/mypath"/>
URI:统一资源标识 组成跟URL基本一样
Uri:sun://www.sun.com/shuyi
URL:网址,统一资源定位符
http://www.baidu.com/index.html
http:// ----scheme 协议
www.baidu.com ---host 主机地址
index.html ----path 路径
III.action+category+data+mimeType(增加了一个过滤条件)
<data android:scheme="myscheme" android:mimeType="image/*"/>
但是这里有一个问题要大家注意一下:当data和mimeType同时存在时,不要单独通过setData或setType方法进行设置,需要使用setDataAndType进行设置。
至于这里的代码,我写的不是很全,大家可以去网上搜一搜,代码还是很多的~不好意思啦!