Android 四大组件之 Activity 解析(下)

segmentfault 对 mackdown 语法的支持不是很好,有些图片都显示不出来,大家可以去我的掘金查看这篇文章。

一、Activity 回顾

<font face= 黑体>在 完全看懂 Android 四大组件之 Activity(上)中我们已经讲了 Activity 的启动方法生命周期以及启动模式。这一节我们来讲一下 Activity 之间的传参以及如何启动系统 Activity 这两大知识点。其中 Activity 之间的传参又包括利用 Intent 传参利用Bundle传参以及复杂数据的传递

二、Activity 之间的数据传递

2.1、利用 Intent 传递数据

<font face= 黑体>利用 Intent 传递数据主要是调用 Intent.putExtra() 方法,这个方法有两个参数,第一个参数是 name,第二个参数是 value,value 的类型如下所示:

Intent方法
<font face= 黑体>传递数据的具体代码如下所示:

// 1、利用 Intent 传递数据
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("str", "Android 开发");  // 传递 String
intent.putExtra("flag", true);
startActivity(intent);

<font face= 黑体>传递的代码已经写完了,那么怎么接收呢?我们可以在 SecondActivity 利用 getIntent() 方法接收数据,具体如下所示:

TextView params = findViewById(R.id.tv_params);
// 接收数据
String str = getIntent().getStringExtra("str");
// 这里的 false 是默认值的意思,如果没有接收到 flag 的值就是 false
boolean flag = getIntent().getBooleanExtra("flag", false);
if (flag) {
    params.setText(str);
} else {
    params.setText("没有接受到数据");
}

<font face= 黑体>我们来看下效果:

传递数据

2.2、利用 Bundle 传递数据

<font face= 黑体>利用 Bundle 传递数据主要是是利用 Bundle 先将要传递的数据存储起来,然后再将 Bundle 数据集传递给需要接收的 Activity,我们来看下传递的代码:

// 2、利用 Bundle 传递数据
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
Bundle bundle = new Bundle();
bundle.putString("str", "Android 开发");
bundle.putBoolean("flag", true);
intent.putExtra("myBundle", bundle);    
startActivity(intent);

<font face= 黑体>接收 Bundle 也很简单,我们只需要调用 getIntent().getBundleExtra() 方法就可以了,我们来看下代码:

Bundle bundle = getIntent().getBundleExtra("myBundle");
if (bundle != null) {
    String str = bundle.getString("str");
    boolean flag = bundle.getBoolean("flag");
    if (flag) {
        params.setText(str);
    } else {
        params.setText("没有接受到数据");
    }
}

<font face= 黑体>Bundle 传递数据跟 Intent 传递数据效果上是完全一样的,只是写法上有点不同而已。

2.3、Activity 间复杂数据的传递

<font face= 黑体>上面这两个方法,可以传递任何基本类型的数据,但是如果想传递一个复杂的数据(比如一个对象),那么要怎么办呢?Android 给我们提供了两种方法来传递复杂类型的数据:

2.3.1、把需要传递的类实现 Serilziable 接口

<font face= 黑体>这里我们创建一个 UserInfo 类来实现 Serilziable 接口,具体代码如下所示:

import java.io.Serializable;

public class UserInfo implements Serializable {
    public String username;
    public int age;
    public int gender;
}

<font face= 黑体>传递的代码如下所示:

// 3、复杂类型的数据传递  实现 Serializable 接口
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
UserInfo userInfo = new UserInfo();
userInfo.username = "Bob";
userInfo.age = 25;
userInfo.gender = 1;
intent.putExtra("userInfo", userInfo);
startActivity(intent);

<font face= 黑体>接收 Serializable 对象,我们需要调用 getIntent().getSerializableExtra() 方法,我们来看下代码:

UserInfo userInfo = (UserInfo) getIntent().getSerializableExtra("userInfo");
if (userInfo != null) {
    String str = "名字:" + userInfo.username + " " + "年龄:" + userInfo.age + " " + "性别:" +
            (userInfo.gender == 1 ? "男" : "女");
    params.setText(str);
}

<font face= 黑体>我们来看下效果:

对象数据

2.3.2、把需要传递的类实现 Parceable 接口

<font face= 黑体>这里我们创建一个 Order 类来实现 Parceable 接口,我们只需要去重写 describeContents 方法和 writeToParcel 方法就可以了,Creator 是自动生成的,具体代码如下所示:

public class Order implements Parcelable {

    public String address;
    public boolean isReceived;
    public int count;

    public Order() {
    }

    protected Order(Parcel in) {
        address = in.readString();
        isReceived = in.readByte() != 0;
        count = in.readInt();
    }

    public static final Creator<Order> CREATOR = new Creator<Order>() {
        @Override
        public Order createFromParcel(Parcel in) {
            return new Order(in);
        }

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

    @Override
    public int describeContents() {
        // 只有当对象中存在文件描述符的时候才需要返回 1,通常情况下返回 0 即可
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(address);
        dest.writeBoolean(isReceived);
        dest.writeInt(count);
    }
}

<font face= 黑体>传递的代码如下所示:

// 4、复杂类型的数据传递  实现 Parcelable 接口
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
Order order = new Order();
order.address = "测试地址";
order.isReceived = true;
order.count = 5;
intent.putExtra("order", order);
startActivity(intent);

<font face= 黑体>接收 Parcelable 对象,我们需要调用 getIntent().getParcelableExtra() 方法,我们来看下代码:

Order order = getIntent().getParcelableExtra("order");
if (order != null) {
    String str = "地址:" + order.address + " " + "购买数量:" + order.count + " " + "是否已经确认收货:" +
            (order.isReceived ? "是" : "否");
    params.setText(str);
}

<font face= 黑体>我们来看下效果:

复杂数据

2.4、Activity 数据回传

<font face= 黑体>当第二个 Activity 需要回传数据到第一个 Activity 的时候,我们只需要通过 startActivityForResult() 方法来启动第二个 Activity 即可,当第二个 Activity 关闭的时候,Android 系统会回调第一个 Activity 的 onActivityResult() 方法,在这个方法里面我们可以获取第二个 Activity 回传过来的一些数据。

<font face= 黑体>MainActivity 具体代码如下所示:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.btn_start).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 5、Activity 数据回传
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                startActivityForResult(intent, 1000);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        String backData = data.getStringExtra("back_data");
        Log.e("MainActivityTag", "requestCode:" + requestCode + " " + "resultCode:" + resultCode + " " +
                "回传的数据:" + backData);
    }
}

<font face= 黑体>SecondActivity 具体代码如下所示:

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        Intent intent = new Intent();
        intent.putExtra("back_data", "回传数据是。。。。。。。。");
        setResult(RESULT_OK, intent);
    }
}

<font face= 黑体>结果如下所示:

在这里插入图片描述

三、启动系统的 Activity

<font face= 黑体>Android 系统常用的 Activity 组件包括拨打电话发送短信以及打开相机,启动方法分别是:

  • <font face= 黑体>intent.setAction(Intent.ACTION_DIAL);
  • <font face= 黑体>intent.setAction(Intent.ACTION_SENDTO)
  • <font face= 黑体>intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE)

<font face= 黑体>具体代码如下所示:

  1. 拨打电话

    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_DIAL);
    startActivity(intent);
  2. 发送短信

    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_SENDTO);
    Uri smsToUri = Uri.parse("smsto:" + 10086);
    intent.setData(smsToUri);
    intent.putExtra("sms_body", "短信内容");
    startActivity(intent);
  3. 打开相机

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

<font face= 黑体>具体效果如下所示:
演示

四、小结

<font face= 黑体>到这里为止,我们已经讲了 Activity 的五种启动方法生命周期四种启动模式Activity 之间数据的传递如何启动系统 Activity 组件

阅读 99

推荐阅读
Android技术学习
用户专栏

一个分享Android相关知识的专栏,有时候也会写一些Kotlin相关技术博客。

0 人关注
21 篇文章
专栏主页