Android学习笔记-Activity的启动模式

Activity的启动模式——standard

  • standard是Activity默认的启动模式,在不进行显式指定的情况下,所有Activity都会自动使用这种启动模式。

  • 在standard模式下,每当启动一个新的Activity,它就会在返回栈中入栈,并处于栈顶的位置。

  • 对于使用standard模式的Activity,系统不会在乎这个Activity是否已经在返回栈中存在,每次启动都会创建一个该Activity的新实例。

在这里插入图片描述

代码演示,创建一个Activity,在该Activity中启动一个新的Activity,启动模式不设置(默认为standard
FirstActivity:

package com.easycol.reactivitylifecycle

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import kotlinx.android.synthetic.main.activity_first.*

class FirstActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_first)

        Log.d("FirstActivity", "FirstActivity onCreate")

        button.setOnClickListener{
            val intent = Intent(this, FirstActivity::class.java)
            startActivity(intent)
        }
    }

    override fun onStart() {
        super.onStart()
        Log.d("FirstActivity", "FirstActivity onStart")
    }

    override fun onResume() {
        super.onResume()
        Log.d("FirstActivity", "FirstActivity onResume")
    }
}

activity_first.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=".FirstActivity">

    <TextView
        android:id="@+id/text"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="15dp"
        android:textSize="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textAlignment="center"
        android:textColor="@color/colorPrimaryDark"
        android:text="第一个页面"/>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/text"
        android:layout_marginTop="15dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:textAllCaps="false"
        android:text="启动一个另一个FirstActivity"
        android:textSize="20dp"
        android:textColor="@color/colorPrimaryDark"/>

</androidx.constraintlayout.widget.ConstraintLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.easycol.reactivitylifecycle">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".FirstActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

在这里插入图片描述

启动程序:

2020-10-01 17:41:16.917 26751-26751/com.easycol.reactivitylifecycle D/FirstActivity: FirstActivity onCreate
2020-10-01 17:41:16.927 26751-26751/com.easycol.reactivitylifecycle D/FirstActivity: FirstActivity onStart
2020-10-01 17:41:16.933 26751-26751/com.easycol.reactivitylifecycle D/FirstActivity: FirstActivity onResume

删除打印,点击按钮:

2020-10-01 17:42:27.036 26751-26751/com.easycol.reactivitylifecycle D/FirstActivity: FirstActivity onCreate
2020-10-01 17:42:27.046 26751-26751/com.easycol.reactivitylifecycle D/FirstActivity: FirstActivity onStart
2020-10-01 17:42:27.048 26751-26751/com.easycol.reactivitylifecycle D/FirstActivity: FirstActivity onResume

说明新创建了一个Activity。

Activity的启动模式——singleTop

  • 当Activity的启动模式指定为singleTop,在启动Activity时如果发现返回栈的栈顶已经是该Activity,则认为可以直接使用它,不会再创建新的Activity实例。
    在这里插入图片描述

还是刚才的代码,设置FirstActivity的启动模式为singleTop

<activity android:name=".FirstActivity"
            android:launchMode="singleTop">

启动程序:

2020-10-01 17:45:53.303 26965-26965/com.easycol.reactivitylifecycle D/FirstActivity: FirstActivity onCreate
2020-10-01 17:45:53.313 26965-26965/com.easycol.reactivitylifecycle D/FirstActivity: FirstActivity onStart
2020-10-01 17:45:53.316 26965-26965/com.easycol.reactivitylifecycle D/FirstActivity: FirstActivity onResume

删除打印,点击按钮:

2020-10-01 17:46:27.347 26965-26965/com.easycol.reactivitylifecycle D/FirstActivity: FirstActivity onResume

说明并没有创建新的Activity,复用了已经创建的FirstActivity

Activity的启动模式——singleTask

  • 当Activity的启动模式指定为singleTask,每次启动该Activity时,系统首先会在返回栈中检查是否存在该Activity的实例,如果发现已经存在则直接使用该实例,并把在这个Activity之上的所有其他Activity统统出栈,如果没有发现就会创建一个新的Activity实例。

在这里插入图片描述

代码演示:在前面代码的基础上,新建一个Activity(SecondActivity

修改FirstActivity的代码,并设置FirstActivity的启动模式为singleTask,代码如下:
FirstActivity

package com.easycol.reactivitylifecycle

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import kotlinx.android.synthetic.main.activity_first.*

class FirstActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_first)

        Log.d("FirstActivity", "FirstActivity onCreate")

        button.setOnClickListener{
            val intent = Intent(this, FirstActivity::class.java)
            startActivity(intent)
        }

        button1.setOnClickListener{
            val intent = Intent(this, SecondActivity::class.java)
            startActivity(intent)
        }
    }

    override fun onStart() {
        super.onStart()
        Log.d("FirstActivity", "FirstActivity onStart")
    }

    override fun onResume() {
        super.onResume()
        Log.d("FirstActivity", "FirstActivity onResume")
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d("FirstActivity", "FirstActivity onDestroy")
    }
}

activity_first.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=".FirstActivity">

    <TextView
        android:id="@+id/text"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="15dp"
        android:textSize="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textAlignment="center"
        android:textColor="@color/colorPrimaryDark"
        android:text="第一个页面"/>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/text"
        android:layout_marginTop="15dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:textAllCaps="false"
        android:text="启动另一个FirstActivity"
        android:textSize="20dp"
        android:textColor="@color/colorPrimaryDark"/>

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/button"
        android:layout_marginTop="15dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginStart="15dp"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp"
        android:textAllCaps="false"
        android:text="启动SecondActivity"
        android:textSize="20dp"
        android:textColor="@color/colorPrimaryDark"/>



</androidx.constraintlayout.widget.ConstraintLayout>

SecondActivity

package com.easycol.reactivitylifecycle

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import kotlinx.android.synthetic.main.activity_first.*

class SecondActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)

        Log.d("SecondActivity", "SecondActivity onCreate")

        button.setOnClickListener{
            val intent = Intent(this, FirstActivity::class.java)
            startActivity(intent)
        }
    }

    override fun onStart() {
        super.onStart()
        Log.d("SecondActivity", "SecondActivity onStart")
    }

    override fun onResume() {
        super.onResume()
        Log.d("SecondActivity", "SecondActivity onResume")
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d("SecondActivity", "SecondActivity onDestroy")
    }
}

activity_second.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=".SecondActivity">

    <TextView
        android:id="@+id/text"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="15dp"
        android:textSize="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textAlignment="center"
        android:textColor="@color/colorPrimaryDark"
        android:text="第二个页面"/>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/text"
        android:layout_marginTop="15dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:textAllCaps="false"
        android:text="启动FirstActivity"
        android:textSize="20dp"
        android:textColor="@color/colorPrimaryDark"/>


</androidx.constraintlayout.widget.ConstraintLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.easycol.reactivitylifecycle">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".SecondActivity"
            android:launchMode="standard"></activity>
        <activity
            android:name=".FirstActivity"
            android:launchMode="singleTask">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

启动程序,点击启动SecondActivity按钮

在这里插入图片描述

跳转到SecondActivity
在这里插入图片描述

然后点击启动FirstActivity按钮,查看打印结果:
针对FirstActivity:

2020-10-01 21:31:02.598 29467-29467/com.easycol.reactivitylifecycle D/FirstActivity: FirstActivity onCreate
2020-10-01 21:31:02.617 29467-29467/com.easycol.reactivitylifecycle D/FirstActivity: FirstActivity onStart
2020-10-01 21:31:02.626 29467-29467/com.easycol.reactivitylifecycle D/FirstActivity: FirstActivity onResume
2020-10-01 21:31:08.089 29467-29467/com.easycol.reactivitylifecycle D/FirstActivity: FirstActivity onStart
2020-10-01 21:31:08.091 29467-29467/com.easycol.reactivitylifecycle D/FirstActivity: FirstActivity onResume

针对SecondActivity

2020-10-01 21:34:12.367 29568-29568/com.easycol.reactivitylifecycle D/SecondActivity: SecondActivity onCreate
2020-10-01 21:34:12.377 29568-29568/com.easycol.reactivitylifecycle D/SecondActivity: SecondActivity onStart
2020-10-01 21:34:12.379 29568-29568/com.easycol.reactivitylifecycle D/SecondActivity: SecondActivity onResume
2020-10-01 21:34:14.751 29568-29568/com.easycol.reactivitylifecycle D/SecondActivity: SecondActivity onDestroy
  • SecondActivity启动FirstActivity时,并没有创建新的Activity,而是复用了已经创建的FirstActivity,当点击系统返回按钮时,程序直接退出。

Activity的启动模式——singleInstance

  • 当Activity的启动模式指定为singleInstance,会启用一个新的返回栈来管理这个Activity。

  • 假设我们的程序中有一个Activity是允许其他程序调用的,如果想实现其他程序和我们的程序可以共享这个Activity的实例,就可以使用singleInstance模式。

  • 在这种模式下,会有一个单独的返回栈来管理这个Activity,不管是哪个应用程序来访问这个Activity,都共用的同一个返回栈,也就解决了共享Activity实例的问题。

在这里插入图片描述

Kotlin课堂

标准函数with、run和apply

with函数接收两个参数:第一个参数可以是一个任意类型的对象,第二个参数是一个Lambda表达式。with函数会在Lambda表达式中提供第一个参数对象的上下文,并使用Lambda表达式中的最后一行代码作为返回值返回。

示例代码如下:

val result = with(obj) {
      // 这里是obj的上下文
      "value" // with函数的返回值
}

run函数的用法和使用场景其实和with函数是非常类似的,只是稍微做了一些语法改动而已。首先run函数是不能直接调用的,而是一定要调用某个对象的run函数才行;其次run函数只接收一个Lambda参数,并且会在Lambda表达式中提供调用对象的上下文。其他方面和with函数是一样的,包括也会使用Lambda表达式中的最后一行代码作为返回值返回。

示例代码如下:

val result = obj.run {
      // 这里是obj的上下文
      "value" // run函数的返回值
}

apply函数和run函数也是极其类似的,都是要在某个对象上调用,并且只接收一个Lambda参数,也会在Lambda表达式中提供调用对象的上下文,但是apply函数无法指定返回值,而是会自动返回调用对象本身。

示例代码如下:

val result = obj.apply {
      // 这里是obj的上下文
}
// result == obj

定义静态方法

Kotlin没有直接定义静态方法的关键字,但是提供了一些语法特性来支持类似于静态方法调用的写法,如单例类,companion object等,这些语法特性基本可以满足我们平时的开发需求了。

然而如果你确确实实需要定义真正的静态方法, Kotlin仍然提供了两种实现方式:注解和顶层方法。

@JvmStatic注解

class Util {

    companion object {
        @JvmStatic
        fun doAction() {
            println("do action2")
        }
    }

}

顶层方法

fun doSomething() {
    println("do something")
}
©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页