Android:显式 Intent

Intent 机制#

Intent 的功能#

Android 四大组件中除了 Content Provider 是通过 Content Resolver 激活的,其他 3 种组件 Activity、Service和 Broadcast Receiver 都是由 Intent 异步消息激活的。Intent 直译为意图,用于协助应用内部及应用之间的交互与通信。
Intent 负责对一次操作中的动作、涉及到的数据和附加数据进行描述,找到对应的组件将 Intent 传递过去完成操作。这种通用的消息系统将一个组件的请求意图传给另一个组件,在不同的组件之间传递消息,体现了减少组件间耦合的设计理念。

Intent 位于 android.content包中,在使用 Intent 时需要导入该类。

Copy Highlighter-hljs
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 对象

Copy Highlighter-hljs
Intent intent = new Intent(Context packageContext, Class<?> cls)
参数 说明
intent 指定对象名称
packageContext 指定一个启动 Activity 的上下文对象,可以使用 Activity 名来指定
cls 指定要启动的 Activity 所在的类,可以使用 Activity 名来指定

接着应用 startActivity() 方法来启动 Activity。

Copy Highlighter-hljs
public void startActivity (Intent intent)

Intent 传参#

对于 Intent 主要使用 putExtra 方法,通过设置键值对的方式进行传参。

Copy Highlighter-hljs
public Intent putExtra(String name, 其他数据类型 value)

跳转后的 Activity 可以使用一系列 getExtra 方法,通过键来获取参数。

Copy Highlighter-hljs
public String get数据类型Extra(String name)

也可以使用 Bundle 类来携带数据,它类似于 Map 用于存放键值对。Bundle 提供了各种常用类型的 put/get 方法,用于往 Bundle 对象放入数据和从 Bundle 对象里获取数据。Bundle 的内部实际上是使用了 HashMap 类型的变量来存放 put 方法放入的值。例如:

Copy Highlighter-hljs
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。第二种方式可能会传输过多的数据,因此采用第一种方式。

Copy Highlighter-hljs
/设定跳转页面 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 种情况。第一种情况是输入了非数字字符,也就是中文英文等情况,此处可以将字符串类型转换成数字,如果转换失败就捕获抛出的异常。同时人类的肉体是有极限的,也就是身高和体重都有一个上界和下界,因此对于一些明显超出人体极限的数据也不能接收。处理方法是当出现超出范围的数字时,就主动地抛出一个异常。

Copy Highlighter-hljs
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。

Copy Highlighter-hljs
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 设计比较简单,我们使用线性布局来设计。

Copy Highlighter-hljs
<?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 的值,并且根据男女性别不同分别算出正常的体重范围,对用户的身体数据进行健康情况的判断,最后输出。

Copy Highlighter-hljs
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 设计使用线性布局来设计。

Copy Highlighter-hljs
<?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 移动应用开发》,杨谊 主编、喻德旷 副主编,人民邮电出版社

posted @   乌漆WhiteMoon  阅读(895)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2020-10-14 sqli-labs 通关指南:Less 5、6、8
点击右上角即可分享
微信分享提示
CONTENTS