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 = "属于正常范围,
请继续保持!";
        }
        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 移动应用开发》,杨谊 主编、喻德旷 副主编,人民邮电出版社

原文地址:https://www.cnblogs.com/linfangnan/p/15404820.html