3.1 Activity简单介绍
基本介绍
一开始创建完成一个项目之后,在Project文件目录下打开:
这里重点关注三个红框里的文件:
Activity文件:
Activity是一种可以包含用户界面的组件,主要用于和用户进行交互。一个应用程序中可以包含零个或多个Activity,但不包含任何Activity的应用程序很少见。
简单来讲
Activity对应的就是类似手机页面的后端部分。

主题语法部分重点关注红框中的部分,其余部分在项目创建的时候会默认创建好。
我们来看一下红框中的语法是什么意思:
setContentView(R.layout.activity_main)
这里的setContentView意思是:设置内容视图,也就是设置这个Activity的前端页面部分(这个在下面有讲到,就是layout下面的xml文件)。
参数部分暂时不用深究,前面R.layout是固定的,后面的activity_main就是这个Activity的内容视图文件的名称。
xml文件
这里的xml文件是特指在layout文件夹目录下的xml文件,也就是布局的意思,简单的来讲其实就是一个手机页面的前端部分,前端的样式就是在layout下面的xml文件中书写。
AndroidMainifest.xml
这个文件相当于配置文件
重点看两个红框中的内容:
最外层:<application ...> ... </appliction>表示的就是应用。
前面一个...是整体应用的配置,这里暂时不需要了解。
重点看<application>内的内容,也就是<activity>:
<activityandroid:name=".MainActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>
一句一句来看:
android:name=".MainActivity"
这个没什么好说的,就是表示这个Activity的名字,对应的就是刚开始创建的MainActivity。
android:exported="true"
总体来说它的主要作用是:是否支持其它应用调用当前组件。
在Activity中该属性用来标示:当前Activity是否可以被另一个Application的组件启动:
- true允许被启动
- false不允许被启动。
如果被设置为了false,那么这个Activity将只会被当前Application或者拥有同样user ID的Application的组件调用。
简单来讲,如果是
ture那么其他手机应用也可以启动这个Activity,例如我们在其他软件里面打开支付宝页面。 如果是false,那么只有本应用才可以启动。
参照文档:
android:exported 属性详解_ ZhangGeng’s Blog -CSDN博客_android:exported
这个属性一般和下面这个联动使用:
<intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter>
这一块的意思就是**配置主Activity**,一般就是打开APP后进入的**第一个界面**。<br />详细属性暂时不需要知道,只需要知道这个在哪个`<activity>`下面配置,哪个就是主Activity。<br />配置了主Activity的Activity,`android:exported`一般都设置为`ture`,其余一般为`false`。
3.2 Thoast和Menu
Thoast
定义
Toast是Android系统提供的一种非常好的提醒方式,在程序中可以使用它将一些短小的信息通知给用户,这些信息会在一段时间后自动消失,并且不会占用任何屏幕空间,尝试一下如何在Activity中使用Toast。
实例
首先在对应的布局文件xml中,添加一个button组件。
首先在右上角选择Design,把button组件拖拽到屏幕当中。
这里先不需要知道这个组件的详细意义,只需要知道这是一个按钮即可

完成之后切换到Code代码区,会发现多了一串代码,注意其中的id。
接着在MainActivity中的Oncreate()方法内添加如下代码:
val button: Button = findViewById(R.id.button)button.setOnClickListener {Toast.makeText(this, "You clicked Button 1", Toast.LENGTH_SHORT).show()}
这里讲解一下语法:<br />首先是申明变量部分,申明一个类型为`Button`类型的变量`button`,`findViewById`就是通过id寻找组件,括号里面的参数就是`R.id.`id的名称``,这里根据刚刚创建的button组件id为button,所以就是`R.id.button`,所以第一句的意思就是**找到id为button 的组件,并把它赋值给变量button**。<br />接着就是给这个变量设置了**监听事件**,`setOnClickListener`,也就是当这个按钮被点击的时候,会触发**大括号中的行为**。
Toast.makeText(this, "You clicked Button 1", Toast.LENGTH_SHORT).show()
Toast对象调用makeText方法,其中:
this表示Thoast要求的上下文,一般都是this"You clicked Button 1"就是需要弹出的文字内容Toast.LENGTH_SHORT表示显示时间,这里是短时间也就是2000msshow()就是展示信息
Toast.LENGTHLONG和Toast.LENGTH_SHORT分别对应多长时间天下布武-CSDN博客_toast.length_short
运行项目之后点击button之后会有如下界面:
Menu
创建文件
首先在res资源文件目录下创建menu文件夹,在menu文件夹下面创建main.xml文件
添加选项
菜单需要选项,所以在main.xml文件中添加如下代码:
<itemandroid:id="@+id/add_item"android:title="Add"/><itemandroid:id="@+id/remove_item"android:title="Remove"/>
重写方法
设定了菜单之后,需要添加到Activity中去,因为Activity默认是没有菜单的,但是有对应的方法,所以需要在Activity中重写有关菜单的方法:
package com.example.myapplicationimport androidx.appcompat.app.AppCompatActivityimport android.os.Bundleimport android.view.Menuimport android.widget.Buttonimport android.widget.Toastclass MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val button: Button = findViewById(R.id.button)button.setOnClickListener {Toast.makeText(this, "You clicked Button 1", Toast.LENGTH_SHORT).show()}}// 重写菜单方法override fun onCreateOptionsMenu(menu: Menu?): Boolean {//return super.onCreateOptionsMenu(menu)//上面的代码重写为下面的menuInflater.inflate(R.menu.main,menu)return true}}
重写方法的时候一般只要打出`onCreateOptionsMenu`大部分代码就会自动补全。<br />接下来讲解一下重写的代码的意思:
- 首先你会发现这里的
menuInflater好像没有定义就直接使用,因为menuInflater是父类的属性,这里是运用了kotlin的语法糖,相当于getMenuInflater()方法能够得到一个MenuInflater对象(理解为菜单填充对象即可) - 再调用它的
inflate()方法,就可以给当前Activity创建菜单了。 inflate()方法接收两个参数:- 第一个参数用于指定通过哪一个资源文件来创建菜单,这里传入
R.menu.main,R表示资源文件夹下,menu就是刚刚创建的menu文件夹,main就是刚刚创建的main.xml; - 第二个参数用于指定的菜单项将添加到哪一个Menu对象当中,这里直接使用onCreateOptionsMenu()方法中传入的
menu参数。(这里一般都只需要写menu就可以了) - 最后给这个方法返回true,表示允许创建的菜单显示出来,如果返回了false,创建的菜单将无法显示。
设置监听事件
在给Activity中添加完菜单之后,需要给菜单中的选项添加事件,这里还是重写方法: ```kotlin package com.example.myapplication
- 第一个参数用于指定通过哪一个资源文件来创建菜单,这里传入
import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.Menu import android.view.MenuItem import android.widget.Button import android.widget.Toast
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main)
val button: Button = findViewById(R.id.button)button.setOnClickListener {Toast.makeText(this, "You clicked Button 1", Toast.LENGTH_SHORT).show()}}override fun onCreateOptionsMenu(menu: Menu?): Boolean {menuInflater.inflate(R.menu.main,menu)return true}override fun onOptionsItemSelected(item: MenuItem): Boolean {// 传入选择的选项的id 也就是item.itemIdwhen(item.itemId){// 如果是添加选项,就弹出文案是You clicked Add的提示R.id.add_item -> Toast.makeText(this, "You clicked Add", Toast.LENGTH_SHORT).show()// 如果是去除选项,就弹出文案是You clicked Remove的提示R.id.remove_item -> Toast.makeText(this, "You clicked Remove", Toast.LENGTH_SHORT).show()}// 作用同上return true}
}
看一下效果<br /><a name="EMUFj"></a>### 销毁一个Activity一般情况下按**返回**就可以退出当前界面,也就会销毁。<br />当然也可以通过代码进行销毁,只需在事件中添加`finish()`即可```kotlinbutton1.setOnClickListener {finish()}
比较简单就不演示了。
3.3 Intent
Intent是Android程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。Intent一般可用于启动Activity、启动Service以及发送广播等场景,由于Service、广播等概念暂时还未涉及,目光无疑就锁定在了启动Activity上面。
Intent大致可以分为两种:显式Intent和隐式Intent。
显式Intent
我们只需要再添加一个button:
接下来添加一个新的空Activity:
跟着下面步骤即可,后面不要加改动:

接下来在MainActivity文件的OnCreate方法中添加:
val button2:Button = findViewById(R.id.button2)button2.setOnClickListener{val intent:Intent = Intent(this,MainActivity2::class.java)startActivity(intent)}
主要讲解一下`Intent`方法
- 第一个参数
Context要求提供一个启动Activity的上下文;(一般都是this) - 第二个参数
Class用于指定想要启动的目标Activity,通过这个构造函数就可以构建出Intent的“意图”
完整代码为:
package com.example.myapplicationimport android.content.Intentimport androidx.appcompat.app.AppCompatActivityimport android.os.Bundleimport android.view.Menuimport android.view.MenuItemimport android.widget.Buttonimport android.widget.Toastclass MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// 注意id的选择val button2:Button = findViewById(R.id.button2)button2.setOnClickListener{val intent:Intent = Intent(this,MainActivity2::class.java)startActivity(intent)}}}
为了便于观察,我们给新建的Activity设置一个label:<br /><br />运行看一下效果:<br />
隐式Activity
相比于显式Intent,隐式Intent则含蓄了许多,它并不明确指出想要启动哪一个Activity,而是指定了一系列更为抽象的action和category等信息,然后交由系统去分析这个Intent,找出合适Activity去启动。
隐式调用使用得比较少,使用情况为不知道应用的包名,但是又想使用相应的功能,比如打开浏览器、打开邮件、打开应用市场、打开相机应用、打开分享应用等。
一般情况下,想要打开应用内的组件使用上述显式Activity即可,如果想要打开其他应用的Activity,就使用隐式Activity。
action和category
- Action属性:字符串类型,在该属性中可通过一个字符串来表示启动窗口时符合的“动作”。
- category属性:字符串类型,在该属性中可通过一个字符串来表示启动窗口时符合的类别。
实例
把上述代码稍作修改 ```kotlin package com.example.myapplication
import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.Menu import android.view.MenuItem import android.widget.Button import android.widget.Toast
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main)
// 注意id的选择val button2:Button = findViewById(R.id.button2)button2.setOnClickListener{val intent = Intent(Intent.ACTION_VIEW)intent.data = Uri.parse("https://www.baidu.com")startActivity(intent)}}
}
运行结果为:<br /><br />详细语法参见:<br />[android Intent的Action、Category属性_年轻的zhangchang的博客-CSDN博客_android.intent.category.home](https://blog.csdn.net/wangliang198901/article/details/12320221)<a name="jE8xZ"></a>### 向下一个Activity传递数据传递数据的方法很简单,只需要使用`putExtra()方法`即可:```kotlinbutton2.setOnClickListener {// 定义想要传递的数据val data = "Hello MainActivity2, this is from MainActivity"// 定义intentval intent = Intent(this, MainActivity2::class.java)// 传递数据intent.putExtra("extra_data", data)// 启动目标ActivitystartActivity(intent)}
在`putExtra()`方法中,第一个参数是**键值**,第二个是需要传递的**数据**。<br />在下一个Activity调用数据就是通过**键值**调用。
package com.example.myapplicationimport androidx.appcompat.app.AppCompatActivityimport android.os.Bundleimport android.widget.Toastclass MainActivity2 : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main2)val extraData = intent.getStringExtra("extra_data")Toast.makeText(this,extraData,Toast.LENGTH_LONG).show()}}
来看一下效果:<br />
返回数据给上一个Activity
首先在MainActivity中修改intent代码:
button2.setOnClickListener {val intent = Intent(this, MainActivity2::class.java)startActivityForResult(intent, 1)}
startActivityForResult()方法接收两个参数:第一个参数还是Intent;第二个参数是请求码,用于在之后的回调中判断数据的来源。
在MainActivity2里添加一个button3。
MainActivity2中的代码修改如下:
package com.example.myapplicationimport android.content.Intentimport androidx.appcompat.app.AppCompatActivityimport android.os.Bundleimport android.widget.Buttonimport android.widget.Toastclass MainActivity2 : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main2)val button3: Button = findViewById(R.id.button3)button3.setOnClickListener() {val intent = Intent()intent.putExtra("data_return", "Hello MainActivity, this is MainActivity2")setResult(RESULT_OK, intent)finish()}}}
setResult()方法接收两个参数:第一个参数用于向上一个Activity返回处理结果,一般只使用RESULT_OK或RESULT_CANCELED这两个值;第二个参数则把带有数据的Intent传递回去。
然后调用了finish()方法来销毁当前Activity。
最后需要在MainActivity中获取数据,这里需要重新方法:
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")Toast.makeText(this,"We received: $returnedData",Toast.LENGTH_LONG).show()}}}
首先来看重写方法的参数:
- requestCode:表示请求码,这里就是
1。 - resultCode:表示处理结果,这里就是
RESULT_OK。 - data:表示传递的数据
继承父类方法,这个一开始就会写出,不用关心。super.onActivityResult(requestCode, resultCode, data)
接下来就是判断请求码和处理结果:
上述操作是通过点击when (requestCode){1->if (resultCode == RESULT_OK){val returnedData = data?.getStringExtra("data_return")Toast.makeText(this,"We received: $returnedData",Toast.LENGTH_LONG).show()}}
button3返回上一个Activity,而如果点击BACK键返回,则不会传递数据,如果想要点击返回键仍然可以返回数据,需要在MainActivity2中重写方法: ```kotlin package com.example.myapplication
import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Button import android.widget.Toast
class MainActivity2 : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main2) val button3: Button = findViewById(R.id.button3) button3.setOnClickListener() { val intent = Intent() intent.putExtra(“data_return”, “Hello MainActivity, this is MainActivity2”) setResult(RESULT_OK, intent) finish() } }
override fun onBackPressed() {//这里可以不用调用父类方法super.onBackPressed()val intent = Intent()intent.putExtra("data_return","Hello MainActivity, this is MainActivity2")setResult(RESULT_OK,intent)finish()}
}
---<a name="ffPkb"></a>## 3.4 Activity生命周期<a name="Cgn4M"></a>### 返回栈每启动一个新的Activity,就会**覆盖在原Activity之上**,然后点击Back键会销毁最上面的Activity,下面的一个Activity就会重新显示出来。<br />也就是所谓的**先进后出**,类似于数据结构中的`栈`。<br />系统总是会显示**处于栈顶**的Activity给用户。<a name="SnfTX"></a>### Activity状态1. **运行状态**> 当一个Activity位于返回栈的栈顶时,Activity就处于运行状态。2. **暂停状态**> 当一个Activity不再处于栈顶位置,但仍然可见时,Activity就进入了暂停状态。3. **停止状态**> 当一个Activity不再处于栈顶位置,并且完全不可见的时候,就进入了停止状态。4. **销毁状态**> 一个Activity从返回栈中移除后就变成了销毁状态。系统回收Activity的意愿也是由1-4是**从低到高**排列的。<a name="oki0t"></a>### Activity生存期<a name="nwDJm"></a>#### 7个回调方法首先看一下什么是回调方法:<br />[回调方法是什么及其理解 - 随花四散 - 博客园](https://www.cnblogs.com/ouhaitao/p/8547907.html)<br /> 7个回调方法分别为:- **onCreate()**> 在每个Activity中都重写了这个方法,它会在Activity第一次被创建的时候调用。你应该在这个方法中完成Activity的**初始化操作**,比如加载布局、绑定事件等。- **onStart()**> 这个方法在Activity**由不可见变为可见**的时候调用。- **onResume()**> 这个方法在Activity准备好和用户**进行交互**的时候调用。此时的Activity一定位于返回栈的栈顶,并且处于运行状态。- **onPause()**> 这个方法在系统准备去启动或者恢复另一个Activity的时候调用。通常会在这个方法中将一些消耗CPU的资源释放掉,以及保存一些关键数据,但这个方法的执行速度一定要快,不然会影响到新的栈顶Activity的使用。- **onStop()**> 这个方法在Activity**完全不可见**的时候调用。它和onPause()方法的主要区别在于,如果启动的新Activity是一个对话框式的Activity,那么onPause()方法会得到执行,而onStop()方法并不会执行。- **onDestroy()**> 这个方法在Activity被**销毁之前调用**,之后Activity的状态将变为销毁状态。- **onRestart()。**> 这个方法在Activity由停止状态变为运行状态之前调用,也就是Activity被重新启动了<a name="Xz4Tg"></a>#### 三种生存期以上7个方法中除了`onRestart()`方法,其他都是两两相对的:- **完整生存期**:`onCreate()`方法和`onDestroy()`方法之间> 简单来讲就是**Activity的创建和销毁期间**- **可见生存期**:`onStart()`方法和`onStop()`方法之间> 简单来讲就是Activity启动了,但是是**在后台运行**的。- **前台生存期**:`onResume()`方法和`onPause()`方法之间> 简单来说就是Activity在前台使用期间。<a name="rh9EE"></a>#### 体验生命周期代码新建一个`ActivityLifeCycleTest`项目。再创建两个子Activity——`NormalActivity`和`DialogActivity`。<br />代码实现如下:<br />[MainActivity.docx](https://www.yuque.com/attachments/yuque/0/2022/docx/22022942/1647501605689-0901b76a-78b0-4666-81b8-0cd438d395bf.docx?_lake_card=%7B%22src%22%3A%22https%3A%2F%2Fwww.yuque.com%2Fattachments%2Fyuque%2F0%2F2022%2Fdocx%2F22022942%2F1647501605689-0901b76a-78b0-4666-81b8-0cd438d395bf.docx%22%2C%22name%22%3A%22MainActivity.docx%22%2C%22size%22%3A21986%2C%22ext%22%3A%22docx%22%2C%22source%22%3A%22%22%2C%22status%22%3A%22done%22%2C%22download%22%3Atrue%2C%22type%22%3A%22application%2Fvnd.openxmlformats-officedocument.wordprocessingml.document%22%2C%22mode%22%3A%22title%22%2C%22taskId%22%3A%22ua4c86e6c-5cb6-443f-ad3f-05c01287f5b%22%2C%22taskType%22%3A%22upload%22%2C%22id%22%3A%22ua6cd0d1a%22%2C%22card%22%3A%22file%22%7D)<br />日志文件如下:> 生命周期了解即可,就不详细讲解了。<a name="X5UBN"></a>### Activity回收当一个Activity进入了停止状态,是有可能被系统回收的。<br />当你从一个Activity回退到上一个Activity的时候,如果上一个Activity被系统回收了,那么回退的Activity其实是被**重新创建**的。> 这里执行的不是`onRestart`方法,而是重新执行`onCreate`方法。这个时候就可能遇到一个问题,上一个Activity存储的零时数据就不存在了。> 例如在输入框输入的数据。如果想要回收前保存数据,则需要重写`onSaveInstanceState()`方法。<br />`onSaveInstanceState()`方法会携带一个**Bundle类型**的参数,Bundle提供了一系列的方法用于保存数据,比如可以使用`putString()`方法保存**字符串**,使用`putInt()`方法保存**整型数据**,以此类推。<br />每个保存方法需要传入两个参数,第一个参数是**键**,用于后面从Bundle中**取值**,第二个参数是**真正要保存的内容**。<br />举个例子:```kotlinoverride fun onSaveInstanceState(outState: Bundle) {super.onSaveInstanceState(outState)// 需要保存的临时数据val tempData = "Something you just typed"outState.putString("data_key", tempData)}
接下来在Oncreate()方法里面调用即可:
override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)Log.d(tag, "onCreate")setContentView(R.layout.activity_main)savedInstanceState?.let {// 根据键值获取临时存储的数据val tempData = it.getString("data_key")Log.d(tag,"data_key:$tempData")}}
3.5 Activity的启动模式
Activity的启动模式有四种:
- standard(默认)
- singleTop
- singleTask
- singleInstance
可以在AndroidManifest.xml中通过给
<activity android:name=".SecondActivity"android:launchMode="singleInstance"><intent-filter><action android:name="com.example.activitytest.ACTION_START" /><category android:name="android.intent.category.DEFAULT" /><category android:name="com.example.activitytest.MY_CATEGORY" /></intent-filter></activity>
standard
standard是Activity默认的启动模式,在不进行显式指定的情况下,所有Activity都会自动使用这种启动模式。
在standard模式下,每当启动一个新的Activity,它都会新创建一个页面,在返回栈中入栈,并处于栈顶的位置。
系统不会在乎这个Activity是否已经在返回栈中存在,每次启动都会创建一个该Activity的新实例。

singleTop
区别于普通的standard模式,singleTop首先会进行一个判断,判断栈顶是否就是目标Activity,如果不是才会创建一个新的实例。
singleTask
相比较于singleTop模式,singleTask模式如果判断栈顶不是目标Activity,并且目标Activity已经存在,那么会直接让目标Activity上面的所有Activity出栈,从而启动目标Activity,如果目标Activity不存在,则创建一个新的实例。
singleInstance
不同于上面三个模式,设立singleInstance的Activity会拥有一个单独的返回栈:
以下图为例子:
其中FirstActivity和ThirdActivity都是默认模式,SecondActivity就是singleInstance模式。
首先从FirstActivity启动SecondActivity,SecondActivity会进入一个单独的返回栈。
在SecondActivity启动ThirdActivity的时候,ThirdActivity会在返回栈A入栈。
ThirdActivity按下回退键,会在返回栈A中出栈,所以下一个显示的Activity就是FirstActivity。
当FirstActivity在回退的时候,就是返回SecondActivity。
随时随地退出
首先写一个单例类:
package com.example.activitylifecycletest.colletcorimport android.app.Activityobject ActivityCollector {// 定义所有Activities的集合private val activities = ArrayList<Activity>()// 把传入的Activity到添加集合中fun addActivity(activity: Activity) {activities.add(activity)}// 把传入的Activity在集合中去除fun removeActivity(activity: Activity) {activities.remove(activity)}// 遍历集合中的所有Activity,并逐个销毁fun finishAll() {for (activity in activities) {if (!activity.isFinishing) {activity.finish()}}activities.clear()}}
接着写三个Activity进行模拟:<br />前两个:
// 第一个package com.example.activitylifecycletest.testActivitiesimport android.content.Intentimport androidx.appcompat.app.AppCompatActivityimport android.os.Bundleimport android.widget.Buttonimport com.example.activitylifecycletest.Rimport com.example.activitylifecycletest.colletcor.ActivityCollectorclass FirstActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_first)ActivityCollector.addActivity(this)val button1:Button = findViewById(R.id.button)button1.setOnClickListener{val intent = Intent(this,SecondActivity::class.java)startActivity(intent)}}}// 第二个package com.example.activitylifecycletest.testActivitiesimport android.content.Intentimport androidx.appcompat.app.AppCompatActivityimport android.os.Bundleimport android.widget.Buttonimport com.example.activitylifecycletest.Rimport com.example.activitylifecycletest.colletcor.ActivityCollectorclass SecondActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_second)ActivityCollector.addActivity(this)val button2: Button = findViewById(R.id.button2)button2.setOnClickListener{val intent = Intent(this,ThirdActivity::class.java)startActivity(intent)}}}
最后一个Activity调用方法退出:
package com.example.activitylifecycletest.testActivitiesimport android.app.Activityimport androidx.appcompat.app.AppCompatActivityimport android.os.Bundleimport android.widget.Buttonimport com.example.activitylifecycletest.Rimport com.example.activitylifecycletest.colletcor.ActivityCollectorclass ThirdActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_third)ActivityCollector.addActivity(this)val button3:Button = findViewById(R.id.button3)// 调用方法一键退出button3.setOnClickListener{ActivityCollector.finishAll()}}}
这里省略布局文件和配置。
可以参考下面
3.6 标准函数和静态方法
标准函数
with和run以及apply
直接上例子:
val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape")// 定义一个字符串构建对象val builder = StringBuilder()// 对象中不断增加元素builder.append("Start eating fruits.\n")for (fruit in list) {builder.append(fruit).append("\n")}builder.append("Ate all fruits.")val result = builder.toString()println(result)
运行结果如下:<br /><br />上述代码可以化简为:
val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape")val result = with(StringBuilder()) {append("Start eating fruits.\n")for (fruit in list) {append(fruit).append("\n")}append("Ate all fruits.")toString()}println(result)// 或者val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape")val result = StringBuilder().run {append("Start eating fruits.\n")for (fruit in list) {append(fruit).append("\n")}append("Ate all fruits.")toString()}println(result)// 或者val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape")val result = StringBuilder().apply {append("Start eating fruits.\n")for (fruit in list) {append(fruit).append("\n")}append("Ate all fruits.")}println(result.toString())
抽离出来方法如下:
val result = with(obj) {// 这里是obj的上下文"value" // with函数的返回值}val result = obj.run {// 这里是obj的上下文"value" // run函数的返回值}val result = obj.apply {// 这里是obj的上下文}
run和apply 的区别在于,**apply函数无法指定返回值,而是会自动返回调用对象本身**。
实际应用
val intent = Intent(context, SecondActivity::class.java)intent.putExtra("param1", "data1")intent.putExtra("param2", "data2")context.startActivity(intent)// 上述代码可以精简为val intent = Intent(context, SecondActivity::class.java).apply {putExtra("param1", "data1")putExtra("param2", "data2")}context.startActivity(intent)
定义静态方法
我没学会,就不写了,大家自己康康PPT叭。
