Android快速入门之Intent使用详解

Intent传递各种类型的数据

Intent传递简单数据:

我们可以直接通过调用Intent的putExtra()方法存入数据,然后在获得Intent后调用getXxxExtra获得 对应类型的数据;当我们要传递多个数据时,可以使用Bundle对象作为容器,通过调用Bundle的putXxx先将数据 存储到Bundle中,然后调用Intent的putExtras()方法将Bundle存入Intent中,然后获得Intent以后, 调用getExtras()获得Bundle容器,然后调用其getXXX获取对应的数据。

逐个传递数据:

button1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        //逐个发送
        Intent intent=new Intent(FirstActivity.this,SecondActivity.class);
        intent.putExtra("msg_str1","传递的数据");
        intent.putExtra("msg_int1",100);
        startActivity(intent);
        
    }
});

//逐个接收
Intent intent = getIntent();
String name = intent.getStringExtra("msg_str1");
int age = intent.getIntExtra("msg_int1");

批量传送数据:

我们可以通过 Bundle 对象调用 Intent 的 putExtra 方法然后传递数据,Bundle 类默认也是已经实现了 Parcelable 接口的,我们可以直接传递 Bundle 对象

//批量传送
button1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {

        Intent intent=new Intent(FirstActivity.this,SecondActivity.class);
        Bundle bundle = new Bundle();
        bundle.putString("msg_str2", "这是一个数据");
        bundle.putInt("msg_int2", 100);
        //intent.putExtra("bundle",bundle);//1
        intent.putExtras(bundle);//2
        startActivity(intent);

    }
});


//批量接收
//方法一
Bundle bundle = getIntent().getBundleExtra("bundle");
String name = bundle.getString("msg_str2");
int age = bundle.getInt("msg_int2");

//方法二
Bundle bundle = getIntent.getExtras();//2

Intent传递数组:

使用Intent我们是可以传递数组格式的数据:

button1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
    
        Intent intent=new Intent(FirstActivity.this,SecondActivity.class);
        //写入数组://可把StringArray换成其他数据类型,比如int,float等等...
        Bundle bundle = new Bundle();
        bundle.putIntArray("arr_int",new int[]{1,2,3});
        bundle.putStringArray("arr_str", new String[]{"呵呵","哈哈"});

    }
});

//获取数据
Bundle bundle3=getIntent().getExtras();
int[] arr = bundle3.getIntArray("arr_int");
String[] str = bundle3.getStringArray("arr_str");

Intent传递集合:

和传递数组不同,传递集合相对比较复杂,需要分情况处理:
List<基本数据类型或String>

//写入集合:
Intent intent=new Intent(FirstActivity.this,SecondActivity.class);
ArrayList<String> list=new ArrayList<>();
list.add("HeHe");
intent.putStringArrayListExtra("list",list);

//读取集合:
Intent intent1=getIntent();
intent.getStringArrayListExtra("list");

List< Object>:将list强转成Serializable类型,然后传入(可用Bundle做媒介)

//写入集合:  Object类需要实现Serializable接口
Intent intent=new Intent(FirstActivity.this,SecondActivity.class);
Student student=new Student();
student.setName("张三");
student.setAge(20);
List<Student> list=new ArrayList<>();
intent.putExtra("student_list",(Serializable) list);

//读取集合
Intent intent1=getIntent();
List<Student> list1 =(List<Student>) getIntent().getSerializableExtra("student_list");

Map<String, Object>,或更复杂的集合,可以外层套个List进行传递

Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
//传递复杂些的参数 
Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("key1", "value1");
map1.put("key2", "value2");
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
list.add(map1);

Bundle bundle = new Bundle();

//须定义一个list用于在bundle中传递需要传递的ArrayList<Object>,这个是必须要的  
ArrayList bundleList = new ArrayList();
bundleList.add(list);
bundle.putParcelableArrayList("list",bundleList);
intent.putExtras(bundle);
startActivity(intent);

Intent传递对象:

传递序列化对象:
先将对象使用 Gson 先序列化成 Json 字符串,然后作为字符串来使用 Intent,这样我们不需要实现 Sereriable 或者 Paracelable,只需要解析Json字符串即可。

将对象转换为Json字符串,后传递数据:

创建实体类:

public class Student{
    private String name;
    private int age;
    /*
     * Get、Set
     */
}

传递数据:

//写入数据:
Student student=new Student();
student.setName("张三");
student.setAge("20);

Intent intent=new Intent(FirstActivity.this,SecondActivity.class);
intent.putExtra("student",new Gson().toJson(student));
startActivity(intent);

//读取数据:
String studentJson=getIntent().getStringExtra("student");
Student student=new Gson().fromJson(studentJson,Student.class);

使用Serializable实现传递对象:

Serializable是序列化的意思,表示将一个对象转换成可存储可传输的状态。序列化之后的对象可以在网络上进行传输,也可以存储到本地。想要事项序列化,我们只需要实现序列化接口即可。

使用方法:

  • ①业务Bean实现:Serializable接口,写上getter和setter方法
  • ②Intent通过调用putExtra(String name, Serializable value)传入对象实例 当然对象有多个的话多个的话,我们也可以先Bundle.putSerializable(x,x);
  • ③新Activity调用getSerializableExtra()方法获得对象实例: eg:Product pd = (Product) getIntent().getSerializableExtra(“Product”);
  • ④调用对象get方法获得相应参数

样例:

public class Student implements Serializable {
    private String name;
    private int age;
    /*
     * Get、Set
     */
}

//发送数据:
Student student=new Student();
student.setName("张三");
student.setAge(20);
Intent intent=new Intent(FirstActivity.this,SecondActivity.class);
intent.putExtra("student_data",student);
startActivity(intent);

//接收数据
Student student1=(Student)getIntent().getSerializableExtra("student_data");

使用Parcelable实现传递对象:

使用方法:

  • ①业务Bean继承Parcelable接口,重写writeToParcel方法,将你的对象序列化为一个Parcel对象;
  • ②重写describeContents方法,内容接口描述,默认返回0就可以
  • ③实例化静态内部对象CREATOR实现接口Parcelable.Creator
  • ④同样式通过Intent的putExtra()方法传入对象实例,当然多个对象的话,我们可以先 放到Bundle里Bundle.putParcelable(x,x),再Intent.putExtras()即可

注意:写入的 顺序和读取的顺序必须一致。

样例:

实现Parcelable接口的代码示例:

public class Student implements Parcelable {

    private String name;
    private int age;

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(name);
        parcel.writeInt(age);
    }
    public static final Creator<Student> CREATOR = new Creator<Student>() {
        @Override
        public Student createFromParcel(Parcel in) {
            Student student=new Student();
            student.name=in.readString();
            student.age=in.readInt();
            return student;
        }

        @Override
        public Student[] newArray(int size) {
            return new Student[size];
        }
    };

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


}

//发送数据:
Student student=new Student();
student.setName("张三");
student.setAge(20);
Intent intent=new Intent(FirstActivity.this,SecondActivity.class);
intent.putExtra("student_data",student);
startActivity(intent);

//接收数据,通过调用getParcelableExtra方法获取传递过来的对象
Student student1=(Student)getIntent().getParcelableExtra("student_data");

两种序列化方式的比较:

Serializable相对来说实现比较简单,由于把整个对象进行序列化,性能较低,考虑到性能的话推荐使用Parcelable。但是Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下,此时建议使用Serializable。

Intent详解

组件间的枢纽——Intent(意图),Android通信的桥梁,比如我们可以通过:

  • startActivity(Intent)/startActivityForResult(Intent):来启动一个Activity
  • startService(Intent)/bindService(Intent):来启动一个Service
  • sendBroadcast:发送广播到指定BroadcastReceiver

Intent是由action(动作)、data(数据)、类型(type)、component(组件)、Flags(标记)和Extra(扩展信息)等内容组成,每个组成都由相应属性进行表示,并提供设置和获取相应属性的方法。
在这里插入图片描述
Component属性

Component属性用于指明Intent目标组件的类名称,它可以被设置,也可以不被设置。如果不设置Component属性,该Intent称之为隐式Intent,Android会根据Intent中包含的其他属性信息,比如Action、Data/Type、Category进行查找,最终找到一个与之匹配的目标组件。如果设置Component属性,则该Intent成为显式Intent,显示Intent则会根据组件名查找到相应的组件,不再执行上述查找过程。

Data属性:
Data属性通常是用于向Action属性提供操作的数据。Data属性有两部分构成分别是数据的URI和数据的MIME类型。
在这里插入图片描述
Category属性:

Category属性指明一个执行Action的分类,一个Intent对象最多只能包含一个Action属性,但是可以包含多个Category属性。调用Intent.setAction()方法来说设置Action属性值,调用Intent.addCategory()方法为Intent添加Category属性。

在这里插入图片描述

显式Intent与隐式Intent:

  • 显式Intent:通过组件名指定启动的目标组件,比如startActivity(new Intent(A.this,B.class)); 每次启动的组件只有一个
  • 隐式显式Intent:不指定组件名,而指定Intent的Action,Data,或Category,当我们启动组件时, 会去匹配AndroidManifest.xml相关组件的Intent-filter,逐一匹配出满足属性的组件,当不止一个满足时, 会弹出一个让我们选择

显式Intent使用示例

Intent 意图,用于启动Activity、启动服务、发送广播等,承担了Android应用程序三大组件的通信功能。显式意图,启动Activity时明确指定激活组件的名称。

IntentFilter
如果Intent Filter定义的动作、类别、数据(URI和数据类型)与Intent匹配,就会使用Intent Filter所在的组件来处理该Intent。

  • 第一种,在Intent的构造方法中指定被启动的Activity
    Intent intent=new Intent(this,B.class);
    startActivity(intent);
  • 第二种,根据目标组件的包名、全路径名来指定开启组件
    Intent intent=new Intent();
    intent.setClassName(“包名”,”全路径名”);
    startActivity(intent);
  • 第三种,通过设置Intent的Component属性
    ComponentName com=new ComponentName(A.this,B.class);
    Intent intent=new Intent();
    intent.setComponent(com); startActivity(intent);

点击按钮返回Home界面:

Intent it = new Intent();
it.setAction(Intent.ACTION_MAIN);
it.addCategory(Intent.CATEGORY_HOME);
startActivity(it);

点击按钮打开百度页面:

Intent it = new Intent();
it.setAction(Intent.ACTION_VIEW);
it.setData(Uri.parse("http://www.baidu.com"));
startActivity(it);

隐式Intent:

隐式Intent没有明确指定组件名。而是系统根据动作(action)、类别(category)、数据(Uri和数据类型)来找到最合适的组件。

使用隐式意图开启Activity的示例代码如下:

Intent intent=new Intent();
intent.setAction();
startActivity(intent);

显式意图开启组件时必须要指定组件的名称,一般只在本应用程序中切换组件时使用。而隐式意图的功能要比显示意图更加强大,不仅可以开启本应用的组件,还可以开启其他应用的组件,例如打开系统的照相机、浏览器等。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙源lll

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值