一、Activity之间传递消息
在(一)中,我们把数据作为独立的键值对进行传递,那么现在把多条数据打包成一个对象进行传递:
1.假设有一个User类的对象,我们先使用putExtra进行传递
activity_demo06.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Demo02Activity">
<EditText
android:id="@+id/et_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="账号:"
android:hint="请输入账号"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:ignore="MissingConstraints" />
<EditText
android:id="@+id/et_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="密码:"
android:hint="请输入密码"
app:layout_constraintTop_toBottomOf="@+id/et_name"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:ignore="MissingConstraints" />
<Button
android:id="@+id/btn_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登录"
app:layout_constraintTop_toBottomOf="@+id/et_password"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
Demo06Activity.kt
package com.example.review02
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import java.io.Serializable
class Demo06Activity : AppCompatActivity() {
//定义一个User类的对象,我们先使用putExtra进行传递
data class User (val name:String,val age:Int,val gender:String):Serializable
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_demo06)
val btn = findViewById<Button>(R.id.btn_login)
val user = User("ebb",26,"male")
btn.setOnClickListener {
val intent = Intent(this,Demo07Activity().javaClass)
intent.putExtra("user",user)
startActivity(intent)
}
}
}
activity_demo07.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Demo03Activity">
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="activity2"
android:textSize="26sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
Demo07Activity.kt
package com.example.review02
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class Demo07Activity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_demo07)
val user = intent.getSerializableExtra("user") as Demo06Activity.User
println(user)
}
}
2.再使用Bundle来传递
activity_demo08.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Demo02Activity">
<EditText
android:id="@+id/et_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="账号:"
android:hint="请输入账号"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:ignore="MissingConstraints" />
<EditText
android:id="@+id/et_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="密码:"
android:hint="请输入密码"
app:layout_constraintTop_toBottomOf="@+id/et_name"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:ignore="MissingConstraints" />
<Button
android:id="@+id/btn_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登录"
app:layout_constraintTop_toBottomOf="@+id/et_password"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
Demo08Activity.kt
package com.example.review02
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import java.io.Serializable
class Demo08Activity : AppCompatActivity() {
data class User(private val name:String,private val age:Int,private val gender:String):Serializable
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_demo08)
val btn = findViewById<Button>(R.id.btn_login)
val user = Demo06Activity.User("ebb", 26, "male")
btn.setOnClickListener {
val intent = Intent(this,Demo09Activity().javaClass)
val bundle = Bundle()
bundle.putSerializable("user",user)
intent.putExtras(bundle)
startActivity(intent)
}
}
}
activity_demo09.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Demo03Activity">
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="activity2"
android:textSize="26sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
Demo09Activity.kt
package com.example.review02
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class Demo09Activity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_demo09)
val bundle = intent.extras
val user = bundle?.getSerializable("user") as? Demo08Activity.User
println(user)
}
}
二、Activity消息回传
目前我们已经可以从Activity向另一个Activity传递消息。有时候从当前Activity返回上一个Activity时也需要传递消息。这时候需要使用安卓中Activity的消息回传。
activity_demo01.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Demo01Activity">
<Button
android:id="@+id/btn_login01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="有账号?请登录"
tools:ignore="MissingConstraints" />
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="游客"
android:textSize="26sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
Demo01Activity.kt
package com.example.review03
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
class Demo01Activity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_demo01)
val btn = findViewById<Button>(R.id.btn_login01)
btn.setOnClickListener {
val intent = Intent(this,Demo02Activity().javaClass)
val REQUEST_CODE = 1
startActivityForResult(intent,REQUEST_CODE)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == 2) {
val name = data?.getStringExtra("name")
val tvName = findViewById<TextView>(R.id.tv_name)
tvName.text = name
}
}
}
activity_demo02.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Demo02Activity">
<EditText
android:id="@+id/et_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="账号:"
android:hint="请输入账号"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:ignore="MissingConstraints" />
<EditText
android:id="@+id/et_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="密码:"
android:hint="请输入密码"
app:layout_constraintTop_toBottomOf="@+id/et_name"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:ignore="MissingConstraints" />
<Button
android:id="@+id/btn_login01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登录"
app:layout_constraintTop_toBottomOf="@+id/et_password"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
Demo02Activity.kt
package com.example.review03
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
class Demo02Activity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_demo02)
val etName = findViewById<EditText>(R.id.et_name)
val intent = Intent()
intent.putExtra("name",etName.text.toString())
val RESULT_OK = 2
setResult(RESULT_OK,intent)
finish()
}
}
三、Activity的任务栈和启动模式
当我们从Activity_2向Activity_1中回传消息时,调用Activity_2的finish方法,返回到了Activity_1,而不是退出程序。这就是因为安卓中存在任务栈。
在 Android 中,Activity 的启动模式定义了当一个活动已经存在时,系统如何处理新的启动请求。Android 提供了四种不同的启动模式来管理 Activity 的行为。这些启动模式通过在AndroidManifest.xml 文件中的 <activity> 元素中设置 android:launchMode 属性来指定。
standard(标准模式)
这是默认的启动模式。 每次启动一个新的活动时,系统都会创建一个新的实例,并将其放置在任务的顶部。 无论活动是否已经存在,都会创建新的实例。 这意味着,无论何时启动该活动,都会创建该活动的新实例。
singleTop(单顶模式)
在这种模式下,如果新的活动已经位于任务的顶部,且具有相同的类型,则系统不会创建新的实例,而是会重用位于栈顶的现有实例。 如果新的活动不在任务的顶部,系统将会创建新的实例,并将其置于栈顶。 例如应用具有一个主界面或主菜单,用户可能会在任何时候返回到该界面。使用 singleTop 模式可以确保不会创建新的主界面实例。
singleTask(单任务模式)
在这种模式下,系统会为活动创建一个新的任务,并且在这个任务中只能存在一个该类型的实例。 如果已经存在该类型的任务,则系统会将该任务调到前台,而不会创建新的实例。 适合作为应用的入口点的活动。例如应用启动时依次压入主界面和启动页面(比如显式广告),启动完毕后进入主界面,并且不会回退到任何页面。
singleInstance(单实例模式)
在这种模式下,系统会创建一个新的任务,并且该任务只能有一个该类型的实例。 即使从其他应用启动该活动,系统也会在新的任务中创建该活动的实例。 适合作为全局共享的单一资源。例如,一个音乐播放器应用可能会有一个后台播放服务,该服务需要在应用处于前台或后台时播放音乐,而不管用户在应用中的哪个部分。
不管如何调用Activity,该Activity都独立存在于一个任务中。