Android-Intent-《第一行代码》笔记

Intent是Android程序中各组件之间进行交互的一种重要方式。

它可以:                                                                         它分为:

    指明当前组件想要执行的动作                                         显式Intent

    在不同组件之间传递数据                                                 隐式Intent

    启动活动

    启动服务

    发送广播

显示Intent启动活动:

Intent(Context packageContext, Class<?>cls)

这个构造函数接收两个参数,第一个参数Context要求提供一个启动活动的上下文,第二个参数Class则是指定想要启动的目标活动,具体使用:

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

隐式Intent启动活动:

隐式Intent不明确指出想要启动哪一个活动,而是指定了一系列更为抽象的action和category等信息,然后交由系统去分析这个Intent并帮我们找出合适的活动去启动。

Intent intent = new Intent("com.example.activitytest.ACTION_START");
//不指明category时,运行时会传入一个默认的category,android.intent.category.DEFAULT
//每个Intent只能指定一个action,却能指定多个category
//再添加第二个category,自定义category如下:
intent.addCategory("com.example.activitytest.MY_CATEGORY");
startActivity(intent);

所谓合适的活动:就是能够响应这个隐式Intent的活动。需要在AndroidManifest.xml中对此活动进行如下设置:

<activity android:name=".SecondActivity:>
    <intent-filter>
        <action android:name="com.example.activitytest.ACTION_START"/> 指明可以响应的action
        <category android:name="android.intent.category.DEFAULT"/>  指明当前活动能够响应的Intent还有可能带有的category
        <category android:name="com.example.activitytest.MY_CATEGORY"/> 需要注册intent对应的category
    </intent-filter>
</activity>

只有<action>和<category>中的内容同事能够匹配上Intent指定的action和category时,这个活动才能响应intent。
 

->向下一个活动传递数据

比如FirstActivity中的一个字符串,现在想把这个字符串传递给SecondActivity

FirstActivity
String data = "Hello SecondActivity";
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("extra_data", data); //键,传参
intent.putExtra("int_data", 100);
startActivity(intent);
SecondActivity
Intent intent = getIntent();
String data = intent.getStringExtra("extra_data");
Int int_data = intent.getIntExtra("int_data", 0);
Log.d("SecondActivity", data); //log中打印出获取到的data的值
//根据传递的参数不同,不同的使用方式
//整型  getIntExtra()
//布尔  getBooleanExtra()

->返回数据给上一个活动

startActivityForResult()方法接受两个参数,第一个参数还是Intent,第二个参数是请求码,用于再之后的回调中判断数据的来源。

FirstActivity
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivityForResult(intent, 1); //intent,请求码
SecondActivity
Intent intent = new Intent();
intent.putExtra("data_return", "Hello FirstActivity");
setResult(RESULT_OK, intent);
//setResult接收两个参数,第一个参数用与像上一个活动返回处理结果,一般只使用RESULT_OK和RESULT_CANCELED
//第二个参数把带有数据的Intent传递回去
finish();

使用startActivityForResult()方法来启动SecondActivity,在SecondACtivity被销毁之后会回调上一个活动的onActivityResult()方法,需要在FirstActivity中重写这个方法

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case 1:
            if (resultCode == RESULT_OK) {
                String returnedData = data.getStringExtra("data_return");
                Log.d("FirstActivity", returnedData);
            }
            break;
        default:
    }
}

-->putExtra()中所支持的数据类型是有限的,下面介绍其他的传递方式

--->Serializable方式

      Serializable是序列化的意思,表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地,至于序列化的方法也很简单,只需要让一个类去实现Serializable这个接口就可以了。

比如一个Person类,其中包含了name和age这两个字段,想要将它序列化可以这样写:

public class Person implements Serializable{
    private String name;
    private int 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;
    }
}

get set 方法都是用于赋值和读取字段数据的,最重要的是第一行,让Person继承了Serializable接口,这样所有的Person对象就都是可序列化的了。

在FirstActivity中实现:

Person person = new Person();
person.setName("Tom");
person.setAge(20);
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("person_data", person);
startActivity(intent);

在这里创建了Person实例,然后将这个实例传入到putExtra()中,可以这样写是因为person实现了Serializable接口

再SecondActivity中的实现:

Person person = (Person) getIntent().getSerializableExtra("person_data");

这里调用getSerializableExtra()方法来获取通过参数传递过来的序列化对象,接着再将它向下转型成Person对象,这样就实现了使用Intent来传递对象的功能。

-->Parcelable方式

Parcelable方式的实现原理是将一个完整的对象进行分解,而分解后的每一部分都是Intent所支持的数据类型,这样也就实现了传递对象的功能了。

public class Person implements Parcelable {
    private String name;
    private int age;
    ...
    @Override
    public int describeContents() {
        return 0;
    }

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

    public static dinal Parcelable.Creator<Person> CREATOR = new Paecelable.Creator<Person>() {
        @Override 
        public Person createFromPaecel(Parcel source) {
            Person person = new Person();
            person.name = source.readString(); //读取name
            person.age = source.readInt(); //读取age
            return person;
        }
        
        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };
}

Person实现Paecelable接口

必须重写describeContents()writeToPaecel()两个方法。describeContents()直接返回0 就可以了,而writeToPaecel方法中需要调用Parcel的writeXXX方法将Person类的字段一一写出。

还必须在Person类中提供一个名为CREATOR的常量,这里创建了Parcelable。Creatoe接口的一个实现,并将泛型指定为Person

接着需要重写createFromParcel()和newArray()这两个方法,在createFromParcel()方法中读取刚才写出的name和age字段都能,并创建一个person对象进行返回,其中name和age都是调用Parcel的readXXX方法读取到的,注意这里的读取顺序一定要和刚才写出的顺序完全相同。而newArray()方法中只需要new出一个Person数组,并使用方法中传入的size作为数组大小就可以了。

接下来,在FirstActicity中我们仍然可以使用相同的代码来传递Person对象,

Person person = (Person) getIntent().getParcelableExtra("person_data");

Serializable效率比Parcelable低。所以在通常情况下推荐使用Parcelable的方式来实现Intent传递对象的功能。

发布了14 篇原创文章 · 获赞 5 · 访问量 2605

猜你喜欢

转载自blog.csdn.net/XingTina/article/details/103809765