Activity 活动跳转(Java&Kotlin)

在任何正式的APP中,都不可能只有一个Activity。当有多个Activity时,如何从一个Activity进入到另一个Activity呢?答案就是活动跳转。

1. 普通跳转

顾名思义,就是单纯从A到B,不带任何内容。

Java代码:

```java

// 活动跳转,从MainActivity跳转到TestActivity,普通跳转

startActivity(new Intent(MainActivity.this, TestActivity.class));

```

如果把刚才Java里的代码复制到Kotlin里,会需要转译,转译后的Kotlin代码如下:

```kotlin

// 活动跳转,从MainActivity跳转到TestActivity,普通跳转

// MainActivity.this 可以简写成 this

startActivity(Intent(this@MainActivity, TestActivity::class.java))

```

有没有感觉这个看起来比Java的更复杂啊,这当然不行啊,所以我们可以自己写。

```kotlin

// TestActivity 为要跳转的页面

startActivity()

```

就这么简单,不管是从代码上还是从意思上都比Java要简洁明了。要这样使用的话,你的Kotlin需要引入Anko库。首先修改项目的build.gradle,在buildscript里加上:

```groovy

ext.anko_version = '0.10.8'

```

然后修改模块的build.gradle,在dependencies里加上:

```groovy

implementation 'org.jetbrains.anko:anko-common:$anko_version'

```

加完之后Sync同步一样。接着在MainActivity中导入:

```kotlin

import org.jetbrains.anko.startActivity

```

然后就可以直接使用了。

2. 传递数据

实际开发中的页面跳转都不会是单纯的跳转,肯定会携带一些参数的。

Kotlin 代码:

// 传递方 - 通过关键字 to 分隔键与值,前面是键,后面是值。第一种写法

val intent = startActivity(

"id" to 456,

"name" to "晨曦"

)

// 接收方 - 通过 intent.extras?.getInt() 和 getString() 获取相对应键的值

val id = intent.extras?.getInt("id")

val name = intent.extras?.getString("name")

在Android开发中,有时需要根据不同情况动态指定页面的启动模式。由于在AndroidManifest.xml文件中,每个Activity只能指定唯一的启动模式,因此不能直接在代码中设置启动模式。但是,Android允许在代码中手动设置启动标志,这样在调用startActivity方法时就可以运行特定的启动模式。

以下是适用于setFlags方法的几种启动标志的取值说明:

1. Intent.FLAG_ACTIVITY_NEW_TASK:开启一个新任务。该值类似于launchMode="standard",但如果原来不存在活动栈,FLAG_ACTIVITY_NEW_TASK 会创建一个新栈。

2. Intent.FLAG_ACTIVITY_SINGLE_TOP:当栈顶为你跳转的Activity实例时,重用栈顶的实例。该值等同于launchMode="singleTop"。

3. Intent.FLAG_ACTIVITY_CLEAR_TOP:当栈顶存在待跳转的Activity实例时,重新创建一个新实例,并将原实例上方的所有实例加以清除。该值与launchMode="singleTask"类似,但launchMode="singleTask"采用onNewIntent启动原任务,而FLAG_ACTIVITY_CLEAR_TOP 采用先onDestroy再onCreate创建新任务。

4. Intent.FLAG_ACTIVITY_NO_HISTORY:该标志与launchMode="standard"情况类似,但栈中不保存新启动的Activity实例。这样下次无论以何种方式启动该实例,也要走standard的完整流程。

5. Intent.FLAG_ACTIVITY_CLEAR_TASK:该标志非常暴力,跳转到新页面时,栈中的原有实例都被清除。注意:该标志要结合FLAG_ACTIVITY_NEW_TASK 使用,即setFlags的参数为“Intent.FLAG_ACTIVITY_CLEAR_TASK”。

启动模式在Java中可能显得有些繁琐,但在Kotlin中,我们可以通过Anko库提供的`intentFor`函数来简化设置启动标志的过程。例如,要设置`FLAG_ACTIVITY_NEW_TASK`启动标志,可以使用以下Anko写法:

```kotlin

startActivity(intent.newTask())

```

这种简洁的方式非常实用。接下来,我们来看一下所有Java方法对应的Anko库的写法。

首先是`Intent`类的启动标志:

1. `FLAG_ACTIVITY_NEW_TASK`:新建任务

2. `FLAG_ACTIVITY_SINGLE_TOP`:置于栈顶

3. `FLAG_ACTIVITY_CLEAR_TOP`:清空栈顶

4. `FLAG_ACTIVITY_NO_HISTORY`:无历史记录

5. `FLAG_ACTIVITY_CLEAR_TASK`:清除任务

然后是Anko库中的标志设置函数:

1. `newTask()`:新建任务

2. `singleTop()`:置于栈顶

3. `clearTop()`:清空栈顶

4. `noHistory()`:无历史记录

5. `clearTask().newTask()`:清除任务后新建一个任务

最后是对应的Java和Kotlin代码:

Java:

```java

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 新任务

intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); // 置于栈顶

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // 清空栈顶

intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); // 无历史记录

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); // 清除之后新建一个任务

```

Kotlin:

```kotlin

startActivity(intent.newTask()) // 新任务

startActivity(intent.singleTop()) // 置于栈顶

startActivity(intent.clearTop()) // 清空栈顶

startActivity(intent.noHistory()) // 无历史记录

startActivity(intent.clearTask().newTask()) // 清除之后新建一个任务

```

根据提供的内容,重构后的代码如下:

页面跳转分为两种情况:

1. 上一个页面传递请求参数给下一个页面;

2. 上一个页面需要接受下一个页面的返回数据。

在这两种情况下,Kotlin和Java都采用了相同的方法:`startActivityForResult`。下面是用Kotlin和Java实现的示例代码:

Java:

```java

@Override

public void startActivityForResult(Intent intent, int requestCode) {

super.startActivityForResult(intent, requestCode);

}

@Override

protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {

super.onActivityResult(requestCode, resultCode, data);

}

```

Kotlin:

```kotlin

override fun startActivityForResult(intent: Intent?, requestCode: Int) {

super.startActivityForResult(intent, requestCode)

}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {

super.onActivityResult(requestCode, resultCode, data)

}

```