Android:显式 Intent
Intent 机制#
Intent 的功能#
Android 四大组件中除了 Content Provider 是通过 Content Resolver 激活的,其他 3 种组件 Activity、Service和 Broadcast Receiver 都是由 Intent 异步消息激活的。Intent 直译为意图,用于协助应用内部及应用之间的交互与通信。
Intent 负责对一次操作中的动作、涉及到的数据和附加数据进行描述,找到对应的组件将 Intent 传递过去完成操作。这种通用的消息系统将一个组件的请求意图传给另一个组件,在不同的组件之间传递消息,体现了减少组件间耦合的设计理念。
Intent 位于 android.content包中,在使用 Intent 时需要导入该类。
import android.content.Intent;
Intent 的应用#
Intent 可以实现组件间的通信,主要有以下 3 种基本应用:
应用 | 说明 |
---|---|
开启 Activity | 将一个 Intent 对象传递给 startActivity() 方法,可以启动一个新的 Activity,并且还可以携一些必要的数据 |
开启 Service | 将一个 Intent 对象传递给 startService() 方法,可以启动一个 Service 来完成一次操作,或者传递一个新的指令给正在运行的 Service |
传递 Broadcast | 通过任何一个广播方法,都可以将广播传递给所有感兴趣的广播接收者 |
显式 Intent#
Intent 可以分为显式和隐式 2 种,显式 Intent 是在创建 Intent 对象时就指定接收者。在启动 Activity 时必须在 Intent 中指明要启动的 Activity 所在的类。当需要启动其他 Activity 时,同样需要应用 Intent 和 startActivity() 方法来启动需要的 Activity。首先需要创建 Intent 对象:
Intent intent = new Intent(Context packageContext, Class<?> cls)
参数 | 说明 |
---|---|
intent | 指定对象名称 |
packageContext | 指定一个启动 Activity 的上下文对象,可以使用 Activity 名来指定 |
cls | 指定要启动的 Activity 所在的类,可以使用 Activity 名来指定 |
接着应用 startActivity() 方法来启动 Activity。
public void startActivity (Intent intent)
Intent 传参#
对于 Intent 主要使用 putExtra 方法,通过设置键值对的方式进行传参。
public Intent putExtra(String name, 其他数据类型 value)
跳转后的 Activity 可以使用一系列 getExtra 方法,通过键来获取参数。
public String get数据类型Extra(String name)
也可以使用 Bundle 类来携带数据,它类似于 Map 用于存放键值对。Bundle 提供了各种常用类型的 put/get 方法,用于往 Bundle 对象放入数据和从 Bundle 对象里获取数据。Bundle 的内部实际上是使用了 HashMap 类型的变量来存放 put 方法放入的值。例如:
Bundle bundle = new Bundle();
bundle.putString("b_name","Betty");
bundle.putInt("b_age", 11);
bundle.putBoolean("b_boy", false);
intent.putExtras(bundle);
显式 Intent 样例#
程序需求#
设计 2 个界面,第一个页面用户输入性别、身高和体重,计算身体质量指数(Body Mass Index,BMI)并判断。计算公式:BMI = 体重(Kg) % 身高(m) ^ 2,判断根据请参照下表。计算结果在第二个页面展示后,单击返回按钮则返回第一个界面。
成年人 | 女性 | 男性 |
---|---|---|
厌食 | <17.5 | <17.5 |
体重偏轻 | <19.1 | <20.7 |
在正常范围内的理想体重 | 19.1-25.8 | 20.7-26.4 |
略微超重 | 25.8-27.3 | 26.4-27.8 |
超重 | >27.3 | >27.8 |
功能设计#
由于 Activity1 要接收用户的数据,Activity2 要显示 bmi 数值,此时可以有 2 种操作。第一种是 Activity1 只用于接收用户的输入,然后把数据传入 Activity2,完成计算并且输出结果。第二种是 Activity1 接收数据后就把 bmi 数据都算好,然后全部传给 Activity2。第二种方式可能会传输过多的数据,因此采用第一种方式。
/设定跳转页面
Intent intent = new Intent(MainActivity.this, Activity2.class);
//设定键值对,传递数据
intent.putExtra("height", height.toString());
intent.putExtra("weight", weight.toString());
intent.putExtra("gender", gender);
startActivity(intent);
第一种方式对于 Activity1 而言,需要注意非法数据的输入,这个也有 2 种情况。第一种情况是输入了非数字字符,也就是中文英文等情况,此处可以将字符串类型转换成数字,如果转换失败就捕获抛出的异常。同时人类的肉体是有极限的,也就是身高和体重都有一个上界和下界,因此对于一些明显超出人体极限的数据也不能接收。处理方法是当出现超出范围的数字时,就主动地抛出一个异常。
heightText = (EditText) findViewById(R.id.ethigh);
weightText = (EditText) findViewById(R.id.etweight);
try{
//获取身高、体重
height = Double.parseDouble(heightText.getText().toString());
weight = Double.parseDouble(weightText.getText().toString());
if(height < 30 || height > 240 || weight < 20 || weight > 750){
throw new Exception();
}
}catch (Exception e) {
Toast.makeText(MainActivity.this, "非法输入,请重新输入", Toast.LENGTH_SHORT).show();
return;
}
代码编写#
MainActivity#
MainActivity 用于接收用户的输入,然后创建 Intent 对象,然后调用 activity2。
package com.example.myapplication;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.Toast;
import android.os.Bundle;
public class MainActivity extends Activity {
EditText heightText, weightText;
RadioButton manButton, womanButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//定位xml中的体重、身高、性别
heightText = (EditText) findViewById(R.id.ethigh);
weightText = (EditText) findViewById(R.id.etweight);
manButton = (RadioButton) findViewById(R.id.man);
womanButton = (RadioButton) findViewById(R.id.woman);
}
public void onClickButton(View view){
String gender = null;
//获取性别
if(manButton.isChecked()){
gender = "男";
}else if (manButton.isChecked()){
gender = "女";
}
if(heightText.getText().toString() == null || weightText.getText().toString() == null){
//未输入则弹窗提醒
Toast.makeText(MainActivity.this,"输入不完整,请重新输入",Toast.LENGTH_SHORT).show();
}
else{
Double height;
Double weight;
try{
//获取身高、体重
height = Double.parseDouble(heightText.getText().toString());
weight = Double.parseDouble(weightText.getText().toString());
if(height < 30 || height > 240 || weight < 20 || weight > 750){
throw new Exception();
}
}catch (Exception e) {
Toast.makeText(MainActivity.this, "非法输入,请重新输入", Toast.LENGTH_SHORT).show();
return;
}
//设定跳转页面
Intent intent=new Intent(MainActivity.this, Activity2.class);
//设定键值对,传递数据
intent.putExtra("height", height.toString());
intent.putExtra("weight", weight.toString());
intent.putExtra("gender", gender);
startActivity(intent);
}
}
}
Activity1 的 UI 设计比较简单,我们使用线性布局来设计。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
tools:context=".MainActivity" android:id="@+id/coordinatorLayout" android:orientation="vertical">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_marginTop="20dp"
android:text="您的胖瘦合适吗?计算一下BMI吧"
android:textSize="20dp"
android:layout_width="match_parent"
android:layout_height="40dp"
android:id="@+id/textView"/>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_below="@id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="性别:"
android:layout_marginTop="10dp"
android:textSize="20dp"
android:id="@+id/textView2">
</TextView>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<RadioGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/textView2"
android:layout_alignLeft="@id/ethigh"
android:orientation="horizontal">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="20dp"
android:text="男"
android:id="@+id/man"
android:checked="true">
</RadioButton>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="20dp"
android:text="女"
android:id="@+id/woman">
</RadioButton>
</RadioGroup>
</LinearLayout>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/tvhigh"
android:textSize="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="身高(cm):"
android:layout_weight="1"/>
<EditText
android:id="@+id/ethigh"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/tvhigh"
android:layout_alignParentRight="true"
android:hint="请输入身高"
android:layout_weight="2"/>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/tvweight"
android:textSize="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="@+id/tvhigh"
android:layout_below="@+id/tvhigh"
android:text="体重(kg)"
android:layout_weight="1"/>
<EditText
android:id="@+id/etweight"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/tvweight"
android:layout_alignLeft="@+id/ethigh"
android:hint="请输入体重"
android:layout_weight="2"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClickButton"
android:text="查看结果"
android:textSize="20dp"
android:layout_weight="1">
</Button>
</LinearLayout>
</LinearLayout>
Activity2#
Activity2 接收到 MainActivity 的数据计算出 bmi 的值,并且根据男女性别不同分别算出正常的体重范围,对用户的身体数据进行健康情况的判断,最后输出。
package com.example.myapplication;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class Activity2 extends Activity {
TextView BMIText, levelText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_2);
Button button = (Button)findViewById(R.id.buttonone) ;
BMIText = (TextView)findViewById(R.id.Text1);
levelText = (TextView)findViewById(R.id.Text2);
//获取传递来的数据,计算 bmi
Intent intent = getIntent();
Double height = Double.parseDouble(intent.getStringExtra("height").toString());
Double weight = Double.parseDouble(intent.getStringExtra("weight").toString());
Double bmi = Math.round(weight * 10000 / (height * height) * 100) / 100.0;
String gender = intent.getStringExtra("gender");
Double fillWightiLeft, fillWightiRight;
//计算不同性别用户的合适体重范围
if (gender.equals("女")) {
fillWightiLeft = Math.round((19.1 * height * height / 10000 * 100)) / 100.0;
fillWightiRight = Math.round((25.8 * height * height / 10000 * 100)) / 100.0;
} else {
fillWightiLeft = Math.round((20.7 * height * height / 10000 * 100)) / 100.0;
fillWightiRight = Math.round((26.4 * height * height / 10000 * 100)) / 100.0;
}
BMIText.setText("您的合适的体重范围为" + fillWightiLeft.toString() + "~" + fillWightiRight + "kg");
//判断BMI指数属于什么情况
String level = null;
if(bmi < 17.5) {
level = "属于厌食!";
}
else if(gender.equals("男") && bmi < 20.7 || gender.equals("女") && bmi < 19.1){
level = "体重偏轻!";
}
else if(gender.equals("男") && bmi <= 26.4 || gender.equals("女") && bmi <= 25.8){
level = "属于正常范围,\n请继续保持!";
}
else if(gender.equals("男") && bmi <= 27.8 || gender.equals("女") && bmi <= 27.3){
level = "略微超重!";
}
else {
level = "已超重!";
}
levelText.setText("身体质量指数为"+ bmi.toString() +"," + level);
button.setOnClickListener(new OnClickListener() {
//点击按钮返回
@Override
public void onClick(View v) {
//设定跳转页面
Intent intent=new Intent(activity2.this,MainActivity.class);
startActivity(intent);
}
});
}
}
Activity2 的 UI 设计使用线性布局来设计。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="5" >
<TextView
android:layout_marginTop="30dp"
android:id="@+id/Text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp" />
<TextView
android:layout_marginTop="10dp"
android:id="@+id/Text2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20dp" />
<Button
android:id="@+id/buttonone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="返回"
android:textSize="20dp" />
</LinearLayout>
运行效果#
首先是传入正常的数据,进行跳转后输出判断的结果。
接着输入异常的数据,分别输入非数字的字符和超越人类极限的数字。
参考资料#
《零基础学 Android》,明日科技编著,吉林大学出版社
《Android 移动应用开发》,杨谊 主编、喻德旷 副主编,人民邮电出版社
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
2020-10-14 sqli-labs 通关指南:Less 5、6、8