In this tutorial, we’ll be discussing Android Intents and implement them using Kotlin in our application.

在本教程中,我们将讨论Android Intent,并在我们的应用程序中使用Kotlin来实现它们。

  • What are Intents?什么是意图?
  • Types Of Intents?意向类型?
  • Using Intents Between Activities在活动之间使用意图
  • Sending Data Using Android Intents使用Android Intent发送数据
  • Using Parcelable and Serializable to pass objects使用Parcelable和Serializable传递对象
  • Creating shorthand intents创建速记意图

Android意图 (Android Intents)

As the name says Intent is something that’s used to perform some action with respect to the flow of the android application. Intents can be used to:

顾名思义,Intent是用于针对android应用程序流程执行某些操作的东西。 意图可用于:

  • Starting a new activity and passing some data.开始一个新的活动并传递一些数据。
  • Starting Fragments/Communicating between fragments.开始片段/片段之间的通信。
  • Start/End service.启动/结束服务。
  • Launch activities from a broadcast receiver从广播接收器启动活动

In this tutorial, we’ll be looking mainly at intents to handle activities.

在本教程中,我们将主要研究处理活动的意图。

An intent definition mainly consists of an instance of the current activity. We set the component name which can be:
The fully qualified class name of the activity to be called. This type of Intent is an explicit intent.
An action such as URL, phone number, location. It’ll display all the available applications of those types.
This falls under the implicit intent category.

一个意图定义主要由当前活动的一个实例组成。 我们设置的组件名称可以是:
要调用的活动的全限定类名称。 这种类型的意图是显式意图
URL,电话号码,位置之类的操作。 它将显示这些类型的所有可用应用程序。
这属于隐式意图类别。

In Kotlin, following is the way to create an activity.

在Kotlin中,以下是创建活动的方法。

val intent = Intent(this, OtherActivity::class.java)
startActivity(intent)

startActivity would add OtherActivity on the activity stack and launch it.
How does our Application, realise which activity is the first to be invoked?
In the AndroidManifest.xml we set the intent filter with the action android.intent.action.MAIN and category android.intent.category.LAUNCHER on the first activity to be launched when our application opens.

startActivity将在活动堆栈上添加OtherActivity并启动它。
我们的应用程序如何实现首先调用哪个活动?
在AndroidManifest.xml中,我们在应用程序打开时要启动的第一个活动上,通过动作android.intent.action.MAIN和类别android.intent.category.LAUNCHER设置了意图过滤器。

finish() is used to destroy an activity and remove it from the stack.

finish()用于销毁活动并将其从堆栈中删除。

意图标志 (Intent Flags)

Flags are like options that can be set on intents to customise the launch process.
If you start the same activity everytime, a new instance would be created and added onto the activity stack
To prevent this, you can use the flags:
FLAG_ACTIVITY_SINGLE_TOP – If set, the activity will not be launched if it is already running at the top of the activity stack.

标志就像可以在意图上设置以自定义启动过程的选项。
如果您每次都启动相同的活动,则会创建一个新实例并将其添加到活动堆栈中
为了防止这种情况,可以使用标志:
FLAG_ACTIVITY_SINGLE_TOP –如果设置,则如果活动已经在活动堆栈的顶部运行,则不会启动该活动。

intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP

Similarly using a flag FLAT_ACTIVITY_CLEAR_TOP would not launch another instance of the activity if it already exists. This flag would clear all the activities above the activity that’s called and set it on the top of the stack.

类似地,使用FLAT_ACTIVITY_CLEAR_TOP标志不会启动该活动的另一个实例(如果已经存在)。 该标志将清除所调用活动上方的所有活动,并将其设置在堆栈的顶部。

通过意图传递数据 (Passing Data Through Intents)

To pass data onto the new activities we use key value pairs inside the function putExtra, putStringArrayListExtra etc.
putExtra generally passes the basic types such as Int, Float, Char, Double, Boolean, String along with

IntArray…. etc.

传递数据到新的活动中,我们使用函数内键值对putExtraputStringArrayListExtra等。
putExtra通常会传递基本类型,例如Int,Float,Char,Double,Boolean,String和

val intent = Intent(this, OtherActivity::class.java)
intent.putExtra("keyString", "Androidly String data")

These Extras fields are under the hood wrapped into the Bundle object which ultimately holds all the data to be passed.

这些Extras字段位于包装到Bundle对象中的Bundle对象最终包含所有要传递的数据。

To retrieve the data in the other activity, we need to use the extras property over the bundles.

要检索其他活动中的数据,我们需要在bundles上使用extras属性。

Retrieving Data in the new Activity

在新活动中检索数据

val bundle: Bundle? = intent.extras
val string: String? = intent.getString("keyString")
val myArray: ArrayList<String>? = intent.getStringArrayList("myArray")

intent, extras are equivalent to getIntent(), getExtras() in Java.
We’ve used a nullable type Bundle? to prevent NullPointerExceptions when not data exists. Similarly, for the data that’s fetched using the keys, we’ve used the nullable types to prevent NPE that can occur when the key is incorrect.

intentextras等效于Java中的getIntent()getExtras()
我们使用了可为空的Bundle?类型Bundle? 当不存在数据时防止NullPointerExceptions 。 同样,对于使用密钥获取的数据,我们使用了可为空的类型,以防止密钥不正确时发生NPE。

使用可打包和可序列化的数据 (Using Parcelable and Serializable Data)

Sometimes we need to pass a complete object from one activity to another. It’s not possible to do so unless we implement the Parcelable or Serializable interface.

有时我们需要将一个完整的对象从一个活动传递到另一个活动。 除非我们实现Parcelable或Serializable接口,否则不可能这样做。

Difference between Parcelable and Serializable

可打包和可序列化之间的区别

  • Parcelable interface is a part of the Android SDK. Serializable is a standard interface of Java.可打包界面是Android SDK的一部分。 可序列化是Java的标准接口。
  • In Parcelable you need to set all of the data you need to pass in a Parcel object and also override the writeToParcel() methods etc. In serializable implementing the interface is sufficient to pass the data.在Parcelable中,您需要设置需要在Parcel对象中传递的所有数据,并覆盖writeToParcel()方法等。在可序列化的实现中,接口足以传递数据。
  • Parcelable is faster than Serializable.可打包比可序列化更快。

发送包裹数据 (Sending Parcelable Data)

Kotlin comes up with some handy annotations to save us from overriding the writeToParcel() method to set the data on the Parcelable. Instead, we can use @Parcelize annotation as shown below:

Kotlin提供了一些方便的注释,使我们免于重写writeToParcel()方法来设置Parcelable上的数据。 相反,我们可以使用@Parcelize注释,如下所示:

@Parcelize
data class Student(val name: String = "Anupam",val age: Int = 24
) : Parcelable

Note: Currently in your build.gradle you must add the following code for the @Parcelize annotation to work:

注意:当前,在build.gradle中,您必须添加以下代码以使@Parcelize批注起作用:

android {androidExtensions {experimental = true}
//..
....
}

In your Activity you do:

在您的活动中,您可以执行以下操作:

val student = Student()
val intent = Intent(this, OtherActivity::class.java)
intent.putExtra("studentData", student)
startActivity(intent)

发送可序列化的数据 (Sending Serializable Data)

data class Blog(val name: String = "Androidly", val year: Int = 2018) : Serializableval blog = Blog("a", 1)
val intent = Intent(this, OtherActivity::class.java)
intent.putExtra("blogData", blog as Serializable)
startActivity(intent)

Let’s use over above knowledge in our Android Studio Project.

让我们在我们的Android Studio项目中使用以上知识。

项目结构 (Project Structure)

布局代码 (Layout Code)

The code for the activity_main.xml layout is given below:

下面给出了activity_main.xml布局的代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"tools:context=".MainActivity"><Buttonandroid:id="@+id/btnSimpleIntent"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="SIMPLE INTENT" /><Buttonandroid:id="@+id/btnSimpleIntentAndData"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="SIMPLE INTENT WITH DATA" /><Buttonandroid:id="@+id/btnParcelableIntent"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Parcelable Intent" /><Buttonandroid:id="@+id/btnSerializableIntent"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Serializable Intent" /><Buttonandroid:id="@+id/btnBrowserIntent"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Browser Intent" /><Buttonandroid:id="@+id/btnMapsIntent"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Maps Intent" /><Buttonandroid:id="@+id/btnGenericIntent"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Generic Intent" /></LinearLayout>

The code for the activity_other.xml layout is given below:

下面给出了activity_other.xml布局的代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"tools:context=".MainActivity"><TextViewandroid:id="@+id/textView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Intent Data goes here" /></LinearLayout>

活动代码 (Activity Code)

The code for the MainActivity.kt class is given below:

MainActivity.kt类的代码如下:

package net.androidly.androidlyintentsimport android.app.Activity
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.os.Parcelable
import android.view.View
import android.widget.Toast
import android.widget.Toast.LENGTH_LONG
import kotlinx.android.parcel.Parcelize
import kotlinx.android.synthetic.main.activity_main.*
import java.io.Serializable@Parcelize
data class Student(val name: String = "Anupam",val age: Int = 24
) : Parcelabledata class Blog(val name: String = "Androidly", val year: Int = 2018) : Serializableclass MainActivity : AppCompatActivity(), View.OnClickListener {fun Context.gotoClass(targetType: Class<*>) =ComponentName(this, targetType)fun Context.startActivity(f: Intent.() -> Unit): Unit =Intent().apply(f).run(this::startActivity)inline fun <reified T : Activity> Context.start(noinline createIntent: Intent.() -> Unit = {}) = startActivity {component = gotoClass(T::class.java)createIntent(this)}var arrayList = ArrayList<String>()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)btnSimpleIntent.setOnClickListener(this)btnSimpleIntentAndData.setOnClickListener(this)btnParcelableIntent.setOnClickListener(this)btnSerializableIntent.setOnClickListener(this)btnBrowserIntent.setOnClickListener(this)btnMapsIntent.setOnClickListener(this)btnGenericIntent.setOnClickListener(this)arrayList.add("Androidly")arrayList.add("Android")arrayList.add("Intents")}override fun onClick(v: View?) {when (v?.id) {R.id.btnSimpleIntent -> {val intent = Intent(this, OtherActivity::class.java)startActivity(intent)}R.id.btnSimpleIntentAndData -> {val intent = Intent(this, OtherActivity::class.java)with(intent){putExtra("keyString", "Androidly String data")putStringArrayListExtra("arrayList", arrayList)putExtra("keyBoolean", true)putExtra("keyFloat", 1.2f)}startActivity(intent)}R.id.btnParcelableIntent -> {val student = Student()val intent = Intent(this, OtherActivity::class.java)intent.putExtra("studentData", student)startActivity(intent)}R.id.btnSerializableIntent -> {val blog = Blog("a", 1)val intent = Intent(this, OtherActivity::class.java)intent.putExtra("blogData", blog as Serializable)startActivity(intent)}R.id.btnBrowserIntent -> {val url = "https://www.androidly.net"val uri = Uri.parse(url)val intent = Intent(Intent.ACTION_VIEW, uri)if (intent.resolveActivity(packageManager) != null) {startActivity(intent)} else {Toast.makeText(applicationContext, "No application found", LENGTH_LONG).show()}}R.id.btnMapsIntent -> {val loc = "12.9538477,77.3507442"val addressUri = Uri.parse("geo:0,0?q=" + loc)val intent = Intent(Intent.ACTION_VIEW, addressUri)if (intent.resolveActivity(packageManager) != null) {startActivity(intent)} else {Toast.makeText(applicationContext, "No application found", LENGTH_LONG).show()}}else -> start<OtherActivity> {putExtra("keyString", "Androidly Generic Intent")}}}}

In the above code, we’ve used Buttons for each type of Intent.
We’ve used Kotlin’s with expression to prevent setting data over the intent object every time.
Besides, we’ve created three different intents apart from the ones already discussed above.
A browser intent is used to launch the url present in the intent in the browser app.
It uses Intent(Intent.ACTION_VIEW, uri).
A location intent is used to launch the lat,lng location in the maps application.
Both of these are implicit intents.
Lastly, we’ve used a generic intent in which we use the Kotlin’s extension functions and lambda expressions to create a shorthand function to launch an intent.
For this we use the following functions:

在上面的代码中,我们对每种Intent类型都使用了Buttons 。
我们使用Kotlin的with表达式来防止每次都在intent对象上设置数据。
此外,除了上面已经讨论的目的之外,我们还创建了三种不同的目的。
浏览器意图用于启动浏览器应用程序中意图中存在的URL。
它使用Intent(Intent.ACTION_VIEW, uri)
位置意图用于在地图应用程序中启动纬度,经度位置。
两者都是隐含的意图。
最后,我们使用了通用意图,其中我们使用Kotlin的扩展函数和lambda表达式创建速记函数来启动意图。
为此,我们使用以下功能:

fun Context.gotoClass(targetType: Class<*>) =ComponentName(this, targetType)fun Context.startActivity(createIntent: Intent.() -> Unit): Unit =Intent().apply(createIntent).run(this::startActivity)inline fun <reified T : Activity> Context.start(noinline createIntent: Intent.() -> Unit = {}) = startActivity {component = gotoClass(T::class.java)createIntent(this)}

startActivity is an exension function which looks for a higher order function as it’s parameter.
Thanks to this, we can now launch intents in as few lines as:
start<OtherActivity>

startActivity是一个扩展函数,它将寻找更高阶的函数作为其参数。
因此,我们现在可以在以下几行中启动意图:
start<OtherActivity>

The code for the OtherActivity.kt class is given below.

下面给出了OtherActivity.kt类的代码。

package net.androidly.androidlyintentsimport android.content.Context
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_other.*class OtherActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_other)val bundle: Bundle? = intent.extrasbundle?.let {bundle.apply {//Intent with dataval string: String? = getString("keyString")textView.text = stringval myArray: ArrayList<String>? = getStringArrayList("myArray")showToast(message = "MyArrayList size:${myArray?.size}")val arrayList: ArrayList<String>? = getStringArrayList("arrayList")showToast(message = "ArrayList size:${arrayList?.size}")val float: Float? = bundle.get("keyFloat") as Float?var boolean = bundle.get("boolean") as? BooleanshowToast(message = "Float data is:$float")showToast(message = "Boolean data is:$boolean")boolean = bundle.get("keyBoolean") as? BooleanshowToast(message = "Boolean correct key data is:$boolean")}bundle.apply {//Serializable Dataval blog = getSerializable("blogData") as Blog?if (blog != null) {textView.text = "Blog name is ${blog?.name}. Year started: ${blog?.year}"}}bundle.apply {//Parcelable Dataval student: Student? = getParcelable("studentData")if (student != null) {textView.text = "Name is ${student?.name}. Age: ${student?.age}"}}}}private fun showToast(context: Context = applicationContext, message: String, duration: Int = Toast.LENGTH_SHORT) {if (!message.contains("null"))Toast.makeText(context, message, duration).show()}
}

We’ve used let and apply to handle nullable types and prevent doing bundle.field in every line.

我们使用letapply处理可空类型并防止在每一行中执行bundle.field。

The output of the above application in action is given below:

上面应用程序的输出如下:

This brings an end to this tutorial on Android intents in Kotlin. You can download the project from the link below.

这结束了有关Kotlin中Android意图的教程。 您可以从下面的链接下载项目。

AndroidlyIntentsAndroidlyIntents

翻译自: https://www.journaldev.com/37763/android-intent-handling-between-activities-using-kotlin

使用Kotlin在活动之间进行Android意向处理相关推荐

  1. android实例教程_活动之间的Android意向处理示例教程

    android实例教程 In our last Android Tutorial, we discussed the Android Hello World Application. In this ...

  2. android 活动传递数据,如何在Android应用程序的“活动”之间传递数据?

    我有一种情况,在通过登录页面登录后,每个activity上都会有一个退出button . 点击sign-out ,我将传递已登录用户的session id以便退出. 谁能指导我如何使session i ...

  3. android 活动切换动画,android – 在使用ChangeImageTransform共享元素转换的两个活动之间动画化ImageView...

    要在具有共享元素的两个活动之间进行屏幕转换动画, 您可以阅读 this article并按照上述步骤: Enable window content transitions in your theme. ...

  4. Android学习之碎片与活动之间的通信

    一.碎片虽然是嵌入在活动中显示的,但是碎片和活动都是各自存在不同的类当中的,并没有什么明显的方式来直接进行通信的.那么如果要在活动中调用碎片里的方法,在碎片里调用活动的方法,一个碎片调用另一碎片的方法 ...

  5. kotlin 垂直滚动_在Android的Kotlin中检测点击或滚动

    kotlin 垂直滚动 Build a responsive UI that shows or hides the toolbar in response to user clicks whilst ...

  6. 坑中速记整理! 使用 kotlin 写第一个 ReactNative Android 模块

    Kotlin 和 Swift, 两大新宠! 借 ReactNative 熟悉下 kotlin 的用法,不料掉坑里面了.昨晚花了大半夜,趁这会儿思路清晰,把涉及到的一些关键信息,迅速整理下. 最佳的使用 ...

  7. 自发和诱发电生理活动之间的动态关系

    文章来源于微信公众号(茗创科技),欢迎有兴趣的朋友搜索关注. 自发的神经活动波动已被证明会影响感知.认知和行为结果的变化.然而,这些波动形成刺激诱发的神经活动的复杂电生理机制仍有待进一步探索.自发和诱 ...

  8. Android Google Map实例 - 在地图和卫星图之间切换(Android mapview)

    之前讲述的例子中显示的 为地图模式,如何你想使用类似google earth的卫星图模式显示,如何操作? 在android上将变得非常简单: 增加两个Button按钮和两个对应的Button.OnCl ...

  9. Android:《Kotlin 从零到精通Android开发》读书笔记

    原文发布在我的公众号:CnPeng 所有文章将优先发布于公众号,随后才会更新简书. 前前后后整整四十天,终于利用非工作时间读完了 欧阳燊(shen)写的 <Kotlin 从零到精通Android ...

最新文章

  1. 指定域的名称或安全标识(SID)与该域的信任信息不一致
  2. bzoj2111,P2606-[ZJOI2010]排列计数【Lucas,组合计数,dp】
  3. 服务器被一堆系统登录_WIN10做天高服务器客户端登录出现“操作系统原因无法登录”...
  4. 通过数据扩充来扩展数据集
  5. matlab给图像加云,matlab怎么给图像加雾
  6. gof 设计模式 java_javaSE中的GOF设计模式
  7. 新东方 词根词缀 excel_14张图搞定高中英语词汇常见词缀词根!
  8. Apache Tomcat漏洞总结
  9. android测试用例编写
  10. 炸了炸了~翻译器中的王者,科大讯飞翻译器2.0横空出世!| 钛空智慧星球推荐...
  11. EXCEL VBA批量下载URL链接地址图片、URL链接地址图片转为图片
  12. 【算法:leetcode】双指针:142. 环形链表 II 633. 平方数之和
  13. Java web实时进度条整个系统共用(如java上传、下载进度条、导入、导出excel进度条等)...
  14. for...in 和 for...of
  15. 985大学计算机考研报录比,68:1!这所985率先公布2020考研报录比,部分专业数据惊人...
  16. 物联网的物流企业信息集成综合管理平台,主要有哪些特征?
  17. 『论文笔记』TensorFlow1.6.0+Keras 2.1.5+Python3.5+Yolov3训练自己的数据集!
  18. 开票系统导出的OFD文档如何转换PDF格式?
  19. iOS开发 ---- 其他控件,弹窗,滑块,菊花,步进,分段等
  20. 阿里云备案管局审核需要几天能通过?

热门文章

  1. base,override,virtual
  2. [转载] 十种方式拼接Python字符串
  3. [转载] Python(析构函数)
  4. Day04:循环结构(while、do-while、for)
  5. jQuery 实现菜单
  6. android系统中如何通过程序打开某个AccessibilityService
  7. 小米路由通过SSH添加静态路由表之后无法跳转的问题
  8. HTML5_增强可访问性和解决IE兼容性问题
  9. java取得当前日期增加一天或多天
  10. bzoj 1029 贪心