跳转至

Android Activity 启动,携带参数启动

更新日期 2021-11-12
  • 2021-11-12 添加CALL_PHONE
  • 2021-9-1 修改格式
  • 2020-8-24 创建文档

Android Activity 启动,携带参数启动

前面我们大致了解了Activity是一个应用组件,能为用户提供一个界面。以及如何新增activity。 一个App中,通常有多个界面。假设每一个界面对应一个activity,不同界面之间怎么跳转呢?

Intent

通常activity之间的跳转离不开Intent这个类。 Intent,直译为“意图”。我们把信息包裹在intent对象中,然后执行。 比如启动RelativeLayoutGuideAct这个activity。

startActivity(new Intent(getApplicationContext(), RelativeLayoutGuideAct.class));

这里用到一个很常见的方法startActivity (Intent intent)startActivity属于Context类,Activity是Context的子类。

java.lang.Object
       android.content.Context
           android.content.ContextWrapper
               android.view.ContextThemeWrapper
                   android.app.Activity

现在我们知道了,启动activity需要使用Intent,调用startActivity方法。

带参数的跳转

在跳转去下一个页面时,我们可能会想携带一些信息到下一个界面去。例如携带一些文本,数字等等。 或者是一个对象。 这些信息我们可以交给Intent,传递到下一个activity去。下一个activity中拿到我们传入的Intent。

携带基本类型和String

我们直接看intent的方法。

Intent intent = new Intent(getApplicationContext(), SendParamsDemo.class);
intent.putExtra(SendParamsDemo.K_INT, 100);
intent.putExtra(SendParamsDemo.K_BOOL, true);
intent.putExtra(SendParamsDemo.K_STR, "Input string");
startActivity(intent);
intent的putExtra方法,可以传入参数。它接受1个String作为key,然后是具体参数。 例子中我们跳转去了SendParamsDemo。
public class SendParamsDemo extends AbsActivity {

    public static final String K_INT = "k_int";
    public static final String K_BOOL = "k_bool";
    public static final String K_STR = "k_str";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        gotInput();
    }

    private void gotInput() {
        Intent intent = getIntent();
        if (intent != null) {
            int i = intent.getIntExtra(K_INT, -1);
            boolean b = intent.getBooleanExtra(K_BOOL, false);
            String str = intent.getStringExtra(K_STR);
            Log.d(TAG, "gotInput: i:" + i + ", b: " + b + ", str: " + str);
        } else {
            Log.d(TAG, "gotInput: input null.");
        }
    }
}
// log:
// com.rustfisher.tutorial2020 D/rustAppSendParamsDemo: gotInput: i:100, b: true, str: Input string
在这个activity中我们接收到了传入的参数。

观察intent的putExtra方法,我们发现它支持传入很多种参数。

int,byte, char, float, double, long, boolean,string,CharSequence或是它们的数组。 也可以传入Parcelable,Serializable对象或是对象数组。

传入Serializable对象

除了基本类型和String,可以传送对象吗? 答案是肯定的。Intent可以携带Serializable对象。 Serializable本身是一个接口,自定义的对象实现这个接口后,就可以被Intent携带。 比如我们改造一下DataTest类,让它实现Serializable接口。

public class DataTest implements Serializable { // 实现接口

然后将对象送给intent,再启动activity。

Intent intent = new Intent(getApplicationContext(), RecyclerViewDemo2Act.class);
DataTest out = new DataTest("input time", 233, 666, 999);
Log.d(TAG, "startInputData: sending object: " + out);
intent.putExtra(RecyclerViewDemo2Act.K_INPUT_DATA, out);
startActivity(intent);

被启动的activity接受传入的intent并取出对象。

Intent intent = getIntent();
if (intent != null) {
    DataTest d = (DataTest) intent.getSerializableExtra(K_INPUT_DATA);
    // 取出了对象,拿去显示
}

Serializable接口不含任何方法。实现了这个接口的类,系统会自动将其序列化。

我们打印出发送和接收到的对象。

startInputData: sending object: com.rustfisher.tutorial2020.recycler.data.DataTest@fb43df5
getInputData: input data object: com.rustfisher.tutorial2020.recycler.data.DataTest@a588b5c
可以发现这2个对象并不是同一个引用。但它们的“内容”是一样的。对象经历了序列化和反序列化的过程。

值得注意的是,Intent能携带的对象大小并不是无限制的。实际开发中,需要开发者自己预估传输的数据大小。

传送Parcelable对象和传送Serializable对象类似,用同样的存入和取出操作。

打电话

需要申请动态权限CALL_PHONE

<uses-permission android:name="android.permission.CALL_PHONE" />

使用Intent.ACTION_CALL是直接打出去

Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phonenumber));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

使用Intent.ACTION_DIAL会停留在拨号界面

Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phonenumber));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

示例代码

本文也发布在

华为云社区

本站说明

一起在知识的海洋里呛水吧。广告内容与本站无关。如果喜欢本站内容,欢迎投喂作者,谢谢支持服务器。如有疑问和建议,欢迎在下方评论~

📖AndroidTutorial 📚AndroidTutorial 🙋反馈问题 🔥最近更新 🍪投喂作者

Ads