activity的销毁

只要调用finish()方法即可销毁activity。

Intent

intent是Android程序中各组件之间进行交互的一种重要方式,不仅可以指定当前组件要执行的动作,也可以在不同组件传递数据。

activity的跳转

  • 显式跳转,直接确定跳转的类,然后进行跳转
  • 隐式跳转,设定好被跳转activity的响应事件和类别,然后通过触发对应的intent和category进行跳转。
  1. 显示跳转
    Intent有很多构造参数,这里我们选用一个Intent(Context packageContext,Class<?> cls)
    第一个参数需要一个启动的上下文,而我们的Activity实例就是一个context。第二个参数就是要跳转的目的类(他需要接受一个java的类)
    例如:
    1
    2
    3
    4
    5
    6
    button1.setOnClickListenner{
    val intent = Intent(this,SecondActivity::class.java)
    //先构造一个intent
    startActivity(intent)
    //通过这个intent启动一个Activity
    }
  2. 隐式跳转
    隐式跳转并不需要指定想要启动哪一个类,而是指定了一些列更为抽象的action和category等信息,然后交由系统分析。
    一般通过在AndroidManifest.xml中添加一个<intent-filter></intent-filter>标签来实现。
    例如:
    1
    2
    3
    4
    5
    6
    <activity android:name=".SecondActivity">
    <intent-filter>
    <action android:name="top.zfxt.activitytest.ACTION_START"></action>
    <category android:name="android.intent.category.DEFAULT"></category>
    </intent-filter>
    </activity>
    以上内容表示该类会接受一个ACTION_START的启动事件,而且会有一个默认的category,这是所有启动事件都有的默认的启动参数。
    然后需要启动这个类的话
    1
    2
    3
    4
    button1.setOnClickListenner{
    val intent = Intent("top.zfxt.activitytest.ACTION_START")
    startActivity(intent)
    }
    如此就可以实现隐式跳转

更多intent的用法

1. 每个intent只能指定一个action,但是可以指定多个category。因此通过category来实现具体跳转的activity。

例如:
在AndroidManifest.xml中添加<category android:name="top.zfxt.activitytest.MY_CATEGORY">
然后在实例中intent.addCategory("top.zfxt.activitytest.MY_CATEGORY")之后才能正确跳转。
2. 隐式Intent,不仅可以启动自己程序内的Activity,还能启动其他程序的Activity,这使得多个应用程序共享之间的功能成为可能。
继续使用上面的button1作为示例:

1
2
3
4
5
button1.setOnClickListener{
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("https://www.baidu.com")
startActivity(intent)
}

以上内容指定了actionIntent.ACTION_VIEW,然后通过Uri.parse()方法将地址字符解析成一个Uri对象,
然后传递给intent.data。
与此相对应的,在标签中也可以在配置一个对象,包含以下内容

标签 注释
android:scheme 用于指定数据的协议部分,如:https
android:host 用于指定数据的主机名
android:port 用于指定数据的端口部分
android:path 用于指定访问的具体资源路径
android:mimeType 用于指定可以处理的数据类型,支持用通配符的方式

上述Intent.ACTION_VIEW是可以调用浏览器的一个启动事件,当然我们也可以自己定义一个activity,用隐式intent的方式,去接受这个启动事件,但我们不一定能够解析他,只是调用而已。
类似的还有
Intent.ACTION_DIAL
tel:10086
这一串数据可以调用电话簿,并且拨打电话给10086。

传递数据

  1. 向下一个activity传递数据

    1
    2
    3
    4
    5
    button1.setOnClickListenner{
    val intent = Intent(this,SecondActivity::class.java)
    intent.putExtra("extra_data","This is a Test")
    startActivity(intent)
    }

    通过重载putExtra()方法,将内容暂存到intent中,然后通过键值对取出该数据。
    然后在另一个被启动的activity中取出数据

    1
    2
    3
    4
    5
    onCreate(savedInstanceState:Bundle?){
    ...
    val extraData = intent.getStringExtra("extra_data")
    Log.d("SecondActivity","extra data is $extraData")
    }

    通过getStringExtra()方法获取相应的键值,同理,对应的数据类型采用相应的方法如getIntExtra(),getBooleanExtra()等

  2. 返回数据给上一个activity

    startActivityForResult()主要是这个方法,但是这个方法已经弃用,等我学了新的再来补充。

  • registerForActivityResult()
    在 Android 开发中,startActivityForResult() 方法在 Android 10(API 级别 29)中已被弃用,而且在 Android 11(API 级别 30)及更高版本中已完全移除。代替它的方法是使用 registerForActivityResult()。这个新的 API 提供了更加简洁和灵活的方式来处理活动返回结果。

下面是详细的步骤来使用 registerForActivityResult()

步骤 1:在 Activity 或 Fragment 中定义一个 ActivityResultLauncher 对象。

1
private lateinit var someActivityResultLauncher: ActivityResultLauncher<Intent>

步骤 2:在 onCreate() 方法中,为 ActivityResultLauncher 对象赋值并指定回调逻辑。

1
2
3
4
5
6
7
8
9
10
someActivityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
// 在这里处理活动返回的结果
if (result.resultCode == Activity.RESULT_OK) {
// 处理成功的逻辑
val data: Intent? = result.data
// 从 data 中获取数据
} else {
// 处理失败的逻辑
}
}

步骤 3:在需要启动另一个活动的地方,使用 someActivityResultLauncher 启动活动。

1
2
val intent = Intent(this, AnotherActivity::class.java)
someActivityResultLauncher.launch(intent)

步骤 4:在另一个活动中,当需要返回结果时,使用 setResult() 方法设置结果并关闭活动。

1
2
3
4
val resultIntent = Intent()
resultIntent.putExtra("key", value)
setResult(Activity.RESULT_OK, resultIntent)
finish()

这就是使用 registerForActivityResult() 方法来替代 startActivityForResult() 的基本步骤。现在,让我们来看一个完整的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class MainActivity : AppCompatActivity() {

private lateinit var someActivityResultLauncher: ActivityResultLauncher<Intent>

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

someActivityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val data: Intent? = result.data
val value = data?.getStringExtra("key")
// 处理返回的结果
} else {
// 处理失败的逻辑
}
}

val button = findViewById<Button>(R.id.button)
button.setOnClickListener {
val intent = Intent(this, AnotherActivity::class.java)
someActivityResultLauncher.launch(intent)
}
}
}

class AnotherActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_another)

val button = findViewById<Button>(R.id.button)
button.setOnClickListener {
val resultIntent = Intent()
resultIntent.putExtra("key", "Some data")
setResult(Activity.RESULT_OK, resultIntent)
finish()
}
}
}

在这个示例中,点击 MainActivity 中的按钮会启动 AnotherActivity,然后 AnotherActivity 在返回结果之前关闭自身并设置了返回结果。MainActivity 中的 someActivityResultLauncher 的回调函数会在返回结果时被触发,你可以在回调函数中处理返回的结果数据。

这就是使用 registerForActivityResult() 方法来代替 startActivityForResult() 的详细说明和示范。请注意,这个新的 API 仅适用于 Android 11 及更高版本,如果你的目标是更早版本的 Android,则需要考虑其他替代方案。

  • startActivityForResult()
    在android10之前任然是使用这个方法的,所以该学还得学。
    使用:
    1
    2
    3
    4
    button1.setOnClickListenner{
    val intent = Intent(this,SecondActvity::class.java)
    startActivityForResult(intent,1)
    }
    被执行的类放入数据:
    1
    2
    3
    4
    5
    6
    7
    8
    class SecondActivity{
    ...
    val intent = Intent()
    intent.putExtra("data_return","Hello FirstActivity")
    setResult(RESUILT_OK,intent)
    finish()
    //手动销毁activity
    }
    回调函数:
    因为使用的是startActiityForResult()方法,因此,SecondActivity被销毁后,会回调上一个Activity的onActivityResult()方法,因此我们需要重写这个方法来获得数据
    1
    2
    3
    4
    5
    6
    7
    8
    9
    override fun onActivityResult(requestCode:Int, resultCode:Int, data: Intent?){
    super.onActivityResult(requestCode,resultCode,data)
    when(requestCode){
    1 - > if(resultCode == RESULT_OK){
    val returnedData = data?.getStringExtra("data_return")
    Log.d("FirstActivity","returned data is $returnedData")
    }
    }
    }
    onActivityResult()方法有三个参数,第一个requestCode,即我们请就是传入的请求码。第二个resultCode即返回时的处理结果,第三个参数data即携带数据的Intent。