安卓基础之《(4)—Activity组件(2)》

==========在活动之间传递消息==========

五、显示Intent和隐式Intent

1、什么是Intent

Intent是各个组件之间信息沟通的桥梁,它用于Android各组件之间的通信,主要完成下列工作:

(1)标明本次通信请求从哪里来、到哪里去、要怎么走

(2)发起方携带本次通信需要的数据内容,接收方从收到的Intent中解析数据

(3)发起方若想判断接收方的处理结果,Intent就要负责让接收方传回应答的数据内容

2、Intent的组成部分

|-----------|--------------|-------------------------|
| 元素名称 | 设置方法 | 说明与用途 |
| Component | setComponent | 组件,它指定Intent的来源与目标 |
| Action | setAction | 动作,它指定Intent的动作行为 |
| Data | setData | 即Uri,它指定Action要操作的数据路径 |
| Category | addCategory | 类别,它指定Intent的操作类别 |
| Type | setType | 数据类型,它指定消息的数据类型 |
| Extras | putExtras | 扩展信息,它指定装载的Bundle(包裹)信息 |
| Flags | setFlags | 标志位,它指定Activity的启动标志 |

3、显示Intent

显示Intent,直接指定来源Activity与目标Activity,属于精确匹配。它有三种构建方式:

(1)在Intent的构造函数中指定

(2)调用Intent对象的setClass方法指定

(3)调用Intent对象的setComponent方法指定

4、显示调用例子

(1)在Intent的构造函数中指定

java 复制代码
// 1.在Intent的构造函数中指定
Intent intent = new Intent(ActStartActivity.this, ActFinishActivity.class);

(2)调用Intent对象的setClass方法指定

java 复制代码
// 2.调用Intent对象的setClass方法指定
Intent intent = new Intent();
intent.setClass(ActStartActivity.this, ActFinishActivity.class);

(3)调用Intent对象的setComponent方法指定

java 复制代码
// 3.调用Intent对象的setComponent方法指定
Intent intent = new Intent();
ComponentName component = new ComponentName(ActStartActivity.this, ActFinishActivity.class);
intent.setComponent(component);

(4)对于第三方包,ComponentName还可以用包名和类名加载

java 复制代码
ComponentName component = new ComponentName("com.example.chapter04", "com.example.chapter04.ActFinishActivity");

5、隐式Intent

隐式Intent,没有明确指定要跳转的目标Activity,只给出一个动作字符串让系统自动匹配,属于模糊匹配

通常App不希望向外部暴露Activity名称,只给出一个事先定义好的标记串,这样大家约定俗成、按图索骥就好,隐式Intent便起到了标记过滤作用。这个动作名称标记串,可以是自己定义的动作,也可以是已有的系统动作

常见系统动作的取值说明

|-----------------|------------------------------|-----------|
| Intent类的系统动作常量名 | 系统动作的常量名 | 说明 |
| ACTION_MAIN | android.intent.action.MAIN | App启动时的入口 |
| ACTION_VIEW | android.intent.action.VIEW | 向用户显示数据 |
| ACTION_SEND | android.intent.action.SEND | 分享内容 |
| ACTION_CALL | android.intent.action.CALL | 直接拨号 |
| ACTION_DIAL | android.intent.action.DIAL | 准备拨号 |
| ACTION_SENDTO | android.intent.action.SENDTO | 发送短信 |
| ACTION_ANSWER | android.intent.action.ANSWER | 接听电话 |

6、Action分析

以打电话为例:

ACTION_DIAL定义

java 复制代码
public static final String ACTION_DIAL = "android.intent.action.DIAL";

在打电话的Activity里配置了android.intent.action.DIAL,所以你调用ACTION_DIAL就会跳转的打电话页面

如果两个Activity都配置了相同ACTION,会怎么样?会让你选用哪个。和你手机里打开网页,让你选用系统浏览器、360浏览器、UC浏览器,是一样的

7、例子

ActionUriActivity.java

有三个按钮,分别是跳转到打电话页面、跳转到发短信页面、跳转到自己的页面

java 复制代码
package com.example.chapter04;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;


public class ActionUriActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_action_uri);
        findViewById(R.id.btn_dial).setOnClickListener(this);
        findViewById(R.id.btn_sms).setOnClickListener(this);
        findViewById(R.id.btn_my).setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
        String phoneNo = "12345";

        if (view.getId() == R.id.btn_dial) {
            Intent intent = new Intent();
            // 设置Intent动作为准备拨号
            intent.setAction(Intent.ACTION_DIAL);
            // 声明一个拨号Uri
            Uri uri = Uri.parse("tel:" + phoneNo);
            intent.setData(uri);
            startActivity(intent);
        } else if (view.getId() == R.id.btn_sms) {
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_SENDTO);
            Uri uri2 = Uri.parse("smsto:" + phoneNo);
            intent.setData(uri2);
            startActivity(intent);
        } else if (view.getId() == R.id.btn_my) {
            Intent intent = new Intent();
            // 调用chapter03的页面
            // 可以启动已经退出的应用
            intent.setAction("android.intent.action.TEST");
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            startActivity(intent);
        }
    }
}

六、向下一个Activity发送数据

1、Intent使用Bundle对象存放待传递的数据信息

Bundle相当于快递盒

2、Bundle对象操作各类型数据的读写方法说明

|--------|--------------------|--------------------|
| 数据类型 | 读方法 | 写方法 |
| 整型数 | getInt | putInt |
| 浮点数 | getFloat | putFloat |
| 双精度数 | getDouble | putDouble |
| 布尔值 | getBoolean | putBoolean |
| 字符串 | getString | putString |
| 字符串数组 | getStringArray | putStringArray |
| 字符串列表 | getStringArrayList | putStringArrayList |
| 可序列化结构 | getSerializable | putSerializable |

3、接收Intent发过来的Bundle

其实在另一个页面这里,这个Activity已经接收到了发过来的Intent,只需要调用getIntent方法获取Intent,然后再getExtras,这样就能把额外的数据拿出来了

4、Bundle

(1)在代码中发送消息包裹,调用Intent对象的putExtras方法,即可存入消息包裹

(2)在代码中接收消息包裹,调用Intent对象的getExtras方法,即可取出消息包裹

5、例子

ActSendActivity.java

发送页面

java 复制代码
package com.example.chapter04;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class ActSendActivity extends AppCompatActivity {

    private TextView tv_send;

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

        tv_send = findViewById(R.id.tv_send);

        findViewById(R.id.btn_send).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(ActSendActivity.this, ActReceiveActivity.class);
                // 创建一个新包裹
                Bundle bundle = new Bundle();
                bundle.putString("request_time", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                bundle.putString("request_content", tv_send.getText().toString());
                intent.putExtras(bundle);
                startActivity(intent);
            }
        });
    }
}

ActReceiveActivity.java

接收页面

java 复制代码
package com.example.chapter04;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;

public class ActReceiveActivity extends AppCompatActivity {

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

        TextView tv_receive = findViewById(R.id.tv_receive);

        // 从上一个页面传来的Intent中获取Bundle
        Bundle bundle = getIntent().getExtras();
        // 其实在这里,这个活动已经接收到了,只需要调用getIntent方法获取意图,然后再getExtras,这么就能把额外的数据拿出来了
        if (bundle == null) { throw new IllegalArgumentException("Bundle cannot be null"); }
        String request_time = bundle.getString("request_time");
        String request_content = bundle.getString("request_content");
        String desc = String.format("收到请求消息:\n请求时间为%s\n请求内容为%s", request_time, request_content);
        tv_receive.setText(desc);
    }
}
相关推荐
doupoa36 分钟前
内存指针是什么?为什么指针还要有偏移量?
android·c++
非凡ghost2 小时前
PowerDirector安卓版(威力导演安卓版)
android·windows·学习·软件需求
独行soc2 小时前
2026年渗透测试面试题总结-19(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
爱装代码的小瓶子3 小时前
【C++与Linux基础】进程间通讯方式:匿名管道
android·c++·后端
兴趣使然HX4 小时前
Android绘帧流程解析
android
JMchen1235 小时前
Android UDP编程:实现高效实时通信的全面指南
android·经验分享·网络协议·udp·kotlin
黄林晴5 小时前
Android 17 再曝猛料:通知栏和快捷设置终于分家了,这操作等了十年
android
有位神秘人6 小时前
Android获取设备中本地音频
android·音视频
JMchen1236 小时前
Android网络安全实战:从HTTPS到双向认证
android·经验分享·网络协议·安全·web安全·https·kotlin
CS创新实验室6 小时前
Pandas 3 的新功能
android·ide·pandas