zoukankan      html  css  js  c++  java
  • Android之Intent相关知识

    什么是Intent?Intent的作用?

          Intent是一个消息传递对象,我们可以通过它来启动其他组件或者在组件之间传递数据。

    通过Intent启动其他组件

          Intent可以用来启动Activity,Service 和 Broadcast 等组件。通过 Intent 启动 Activity ,只需要创建一个 Intent 对象,并传入要启动的 Activity 的类名,然后调用 startActivity() 方法,传入该 Intent 即可。

        Intent intent = new Intent(MainActivity.this,SecondActivity.class);
        startActivity(intent);

          用 Intent 启动 Service的方法和启动 Activity 的方法相似,只需要知道 Service 类名,构造出 Intent 对象,然后调用 startService() 方法即可。除此之外,我们还可以通过将 Intent 传入sendBroadcast() 等方法中来发送广播。

    通过Intent传递数据

          Intent可以传递的数据类型有很多种,通过查询intent.putExtra()方法可以看到里面可以传入基本类型的数据,Intent也可以传递Bundle 对象,我们可以创建一个Bundle对象,在里面存储数据,再通过 Intent 传递出去。如果想要使用 Intent 传递自定义对象的话,就要先对自定义对象进行序列化才可以。

    Android中想要传递一个自定义的对象通常有两种方法,一种是使用让对象实现Java原有的Serializable接口,另一种就是实现Android中的Parceable接口。

    使用Serializable:

          Serializable的使用方法非常简单,只需要让需要序列化的对象实现Serializable接口即可。查看Serializable接口的源码可以发现,它其实是一个空实现,主要时期到一个标识的作用,表示该对象需要被序列化。java中的 Arraylist 等也都实现了 Serializable 接口,可以被序列化。

    //MainActivity中   
       private void skipTo() {
            Intent intent = new Intent(MainActivity.this,SecondActivity.class);
    //CustomBean是已实现了Serializable接口的自定义对象 ArrayList
    <CustomBean> lists = new ArrayList<>(); //list中存储序列化对象 lists.add(new CustomBean("张三",12)); lists.add(new CustomBean("李四",15)); //保存序列化list intent.putExtra("list",lists); startActivity(intent); } //SecondActivity中 private void getData() { //得到Intent Intent intent = getIntent(); //得到Intent中保存的序列化对象 ArrayList<CustomBean> lists = (ArrayList<CustomBean>) intent.getSerializableExtra("list"); }


          我们使用Serializable,除了让对象只实现该接口之外,最好再为对象指定一个serialVersionUID,这是为了方便它的反序列化。系统对对象进行序列化,首先会寻找当前类中是否有serialVersionUID,如果没有,就自动根据当前类的结构自动生成一个UID,然后序列化时将该serialVersionUID存储到序列化文件中,反序列化时从序列化文件中得到serialVersionUID,然后与当前类的serialVersionUID进行对比,如果相同,则反序列化成功。

          假设我们不手动指定serialVersionUID,当以后对该类进行修改时(比如添加,删除某些属性),它的serialVersionUID就会改变,这样就会使之前存储的序列化数据中的serialVersionUID与当前类的serialVersionUID不一致,导致反序化时失败。

    使用Parceable: 

          比起Serializable,Parceable的使用会稍微复杂一点,它需要自定义对象实现Parceable接口,并实现一些方法:

    public class CustomBean implements Parcelable {
        
        private String name;
        private int age;
    
        public CustomBean(String name, int age) {
            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;
        }
    
        //需要定义一个构造方法,用于从序列化后的对象中创建原始对象
        private CustomBean(Parcel in){
            //注意这里read的顺序要与下面write的顺序保持一致
            this.name = in.readString();
            this.age = in.readInt();
        }
    
        //返回当前对象的内容描述,这里返回0即可
        @Override
        public int describeContents() {
            return 0;
        }
    
        //写入方法
        @Override
        public void writeToParcel(Parcel dest, int flags) {
    //这里write的顺序要与上面read的顺序保持一致 dest.writeString(name); dest.writeInt(age); }
    //还必须提供一个CREATOR常量 public static final Creator<CustomBean> CREATOR = new Creator<CustomBean>() {
    //从序列化的对象中创建原始对象 @Override
    public CustomBean createFromParcel(Parcel in) { return new CustomBean(in); } //创建指定长度的原始对象数组 @Override public CustomBean[] newArray(int size) { return new CustomBean[size]; } }; }

    Serializable与Parcelable区别

          虽然两者都是用于支持序列化、反序列化话操作,但是两者最大的区别在于存储媒介的不同,Serializable是将序列化后的对象存储在硬盘上,使用I/O读写的方式,而Parcelable是将其存储在内存中,是针对内存的读写,因为内存的读写速度远远大于I/O的读写速度,所以Parceable的效率会更高。平常通过Intent 传递自定义对象时,使用Parceable会比较好,如果是要把序列化对象进行较为持久的保存,则使用Serializable会比较好。

    Intent的分类

          Intent可以分为两种:显示Intent和隐式Intent。

          显式 Intent:按名称(完全限定类名)指定要启动的组件。 通常,我们在应用中都是使用显式 Intent 来启动组件,但是这需要知道要启动的 Activity 或 Service 的类名。例如,启动新 Activity 以响应用户操作,或者启动服务以在后台下载文件。

          隐式Intent:不会指定特定要启动的组件,而是会通过Intent-filter(过滤器)中设置的过滤信息进行对比筛选,如果匹配,则启动目标组件,否则不启动。

    Intent-filter的匹配规则:

    一个Intent-filter中包含的过滤信息有action,category,data三类。一个intent-filter中可能会有多个action,category或data,只要intent能保证三类中都至少有一个匹配上,那么就能启动组件。而一个组件中可能会有多个intent-filter,只要匹配其中的任意一个intent-filter中的三个类,就能启动组件。

          action(操作):用来指定所要进行的操作,我们可以通过setAction()方法为Intent设置action。系统中有一些默认的action可供选择,比如默认的入口Actiivty的intent-filter中的action就是设置为ACTION_MAIN,表示这是入口Activity,且不需要Intent。

          category(类别):用于标识目标组件的类别,比如应用中的入口Activity的category就是"CATEGORY_LAUNCHER",表示这个Activity是应用的初始Actiivty。

          data(数据):date有mimeType(媒体类型)和数据Uri两部分组成,intent可通过setDataAndType()来设置data的mimeType和Uri。当intent中设置的data与intent-filter中的data,两者的mimeType和Uri都匹配时,才算data完全匹配成功。

          我们可以在AndroidManifest中为Activity或Service配置intent-filter。如下:

    <activity android:name=".sample.SampleListActivity">
           <intent-filter>
               <action android:name="com.example.mymodeldemos1"/>
               <action android:name="com.example.mymodeldemos2"/>
               <category android:name="android.intent.category.DEFAULT"/>
               <data android:mimeType="text/plain"/>
           </intent-filter>
    </activity>

    文章参考:https://developer.android.com/guide/components/intents-filters.html

  • 相关阅读:
    HDFS入门详解
    Linux find example
    你想建设一个能承受500万PV/每天的网站吗?服务器每秒要处理多少个请求才能应对?
    find 与 tar命令连用
    莫名其妙的主机名 VM_32_234_centos
    hadoop Safe mode is ON 的解决办法
    Does not contain a valid host:port authority: Master:8031 (configuration property 'yarn.resourcemanager.resource-tracker.address')
    Equals 和 == 的区别--转
    线程间操作无效: 从不是创建控件的线程访问它。
    C# EventHandler委托事件小结--百度
  • 原文地址:https://www.cnblogs.com/weimore/p/7833320.html
Copyright © 2011-2022 走看看