基本概念
- 一种可以包含用户界面的组件,主要用于和用户进行交互
一 使用Intent在Activity之间进行穿梭
Intent是Android程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。
- 显式Intent
button.setOnClickListener{
val intent = Intent(this, SecondActivity::class.java)
startActivity(intent)
}
- 隐式Intent
- 通过在<activity>标签下配置<intent-filter>的内容,可以指定当前Activity能够响应的action和category
<activity
android:name=".activity.PswLoginActivity">
<intent-filter>
<action android:name="com.meizu.account.outlib.login" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
- 在<action>标签中指明了当前PswLoginActivity可以响应com.meizu.account.outlib.login这个action。
- 而<category>标签则包含了一些附加信息,更精确的指明了当前Activity能够响应的Intent中还可能带有的category。
- 只有<action>和<category>中的内容同时匹配Intent中指定的action和category时,这个Activity才能响应该Intent。
- 每个Intent中只能指定一个action,但能指定多个category。
button.setOnClickListener{
val intent = Intent("com.meizu.account.outlib.login")
intent.addCategory("com.meizu.account.outlib.MY_CATEGORY")
startActivity(intent)
}
//相应的 <action>标签对里面也要指定
<activity
android:name=".activity.PswLoginActivity">
<intent-filter>
<action android:name="com.meizu.account.outlib.login" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.meizu.account.outlib.MY_CATEGORY" />
</intent-filter>
</activity>
还可以在<intent-filter>标签中再配置一个<data>标签,用于更精准地指定当前Activity能够响应的数据
- android:scheme: 用于指定数据的协议部分,例如https
- android:host: 用于指定数据的主机名部分,例如www.baidu.com
- android:port: 用于指定数据的端口部分,一般紧随主机名之后
只有当<data>标签中指定的内容和Intent中携带的Data完全一致,当前Activity才能响应该Intent<activity android:name=".activity.PswLoginActivity"> <intent-filter> <action android:name="com.meizu.account.outlib.login" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="https" /> </intent-filter> </activity>
调用响应:
button.setOnClickListener{ val intent = Intent("com.meizu.account.outlib.login") //默认category是DEFAULT intent.data = Uri.parse("https:www.baidu.com") startActivity(intent) }
二 Activity之间传递传递与回传
- 通过Intent传递数据给下一个Activity
- 通过startActivityForResult(intent,requestCode)启动另一个Activity
- 另一个Activity通过setResult(resultCode,intent)返回数据
- 复写onActivityResult方法,通过requestCode判断是哪个Activity跳回来的,通过resultCode判断处理结果
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?){
super.onActivityResult(requestCode, resultCode, data)
when(requestCode){
1 -> if(resultCode == RESULT_OK){
val returnData = data?.getStringExtra("...")
}
}
}
三 Activity的生命周期
- onCreate() : 在Activity第一次被创建的时候调用
- onStart() : 在Activity从不可见变为可见的时候调用,还不能交互
- onResume() : Activity准备好和用户进行交互的时候调用,此时Activity一定位于返回栈的栈顶,并且处于运行状态
- onPause() : 这个方法在系统准备去启动或者恢复另一个Activity的时候调用,此时Activity还处于可见状态不可交互
- onStop() : 在Activity完全不可见的时候调用
- onDestroy() : 在Activity被销毁之前调用
-
onRestart() : 在Activity由停止状态变为运行状态之前调用,也就是Activity被重新启动了
Activity生命周期图
Activity被回收了怎么办
比如MainActivity中有一个文本输入框,现输入了一段文字,然后启动另一个Activity,这时由于系统内存不足MainActivity被回收掉了,过一会你又点击了Back键回到MainActivity,会发现刚刚输入的文字都没了,因为MainActivity被重新创建了。
如果出现这种情况是比较影响用户体验的,为此Android提供了onSaveInstanceState()方法。
override fun onSaveInstanceState(outState: Bundle?){
super.onSaveInstanceState(outState)
val tempData = "..."
outState.putString("key", tempData)
}
override fun onCreate(saveInstanceState: Bundle?){
super.onCreate(saveInstanceState)
if(saveInstanceState != null){
val tempData = saveInstanceState.getString("key")
...
}
}
四 Activity的启动模式
Android是使用返回栈来管理Activity的
- standard: 每当启动一个新的Activity,它就会在返回栈中入栈,并处于栈顶的位置,也是Activity的默认启动方式。
- singleTop: 指定此模式启动,在启动Activity时如果发现返回栈的栈顶已经是该Activity,则会复用当前Activity,如果当前Activity并未处于栈顶,则还是会创建新的实例。
- singleTask: 指定此模式启动,系统首先会在返回栈中检查是否存在该Activity实例,如果发现已经存在并且位于栈顶,则会复用该Activity实例,如果不在栈顶则会把这个Activity之上的所有其它Activity统统出栈,如果没有则创建该实例。
- singleInstance: 在这种模式下,会有一个单独的返回栈来管理这个Activity,不管的哪一个应用程序来访问这个Activity,都会共用同一个返回栈,每一个应用程序都会有自己的返回栈,保证该实例全局唯一性。
补充:随时随地退出程序 Activity管理类
object ActivityManager{
private val activities = ArrayList<Activity>()
fun addActivity(activity: Activity){
activities.add(activity)
}
fun removeActivity(activity: Activity){
activities.remove(activity)
}
fun finishAll(){
for(activity in activities){
if(!activity.isFinishing()){
activity.finish()
}
}
activities.clear()
}
}