四大组件
- Activity
- Service
- BroadcastReceiver
- ContentProvider
使用资源,代码中使用 R.string.app_name
,XML中使用 @string/app_name
。
Activity
一个Activity注意3部分:
- 后端文件
src/main/java/com/example/app/XXXActivity.kt
在重写的 onCreate 方法中setContentView(R.layout.activity_main)
使用资源R.layout.activity_app
R.string.app_name
R.资源分类.资源名
省略 findViewById:https://blog.csdn.net/guolin_blog/article/details/113089706 - 前端页面
src/res/layout/activity_app.xml
使用资源 使用已有id:@id/button1
定义一个新id:@+id/button2
- 在 AndroidManifest.xml 中配置
一般创建Activity时自动添加
Intent 实现跳转
不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。Intent一般可用于启动Activity、启动Service以及发送广播等场景
- 显式
// 使用ViewBinding简化了 findViewById var inflate = ActivityMainBinding.inflate(layoutInflater) inflate.button01.setOnClickListener { val intent = Intent(this, SecondActivity::class.java) // 显示Intent,跳到别的Activity startActivity(intent) }
通过返回键销毁新Activity返回到旧的
- 隐式
不明确指出想要启动哪一个Activity,而是指定了一系列更为抽象的action和category等信息,然后交由系统去分析这个Intent,并帮我们找出合适的Activity去启动。
在 AndroidManifest.xml 中配置 intent-filter 执行处理的 action 和 category <activity android:name=".SecondActivity" android:exported="false"> <meta-data android:name="android.app.lib_name" android:value="" /> <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>
inflate.button01.setOnClickListener { // val intent = Intent(this, SecondActivity::class.java) // 显式 val intent = Intent("com.example.activitytest.ACTION_START") // 隐式 intent.addCategory("com.example.activitytest.MY_CATEGORY") // 指定category,和action一起工作,可省略 startActivity(intent) }
- 通过data隐式响应
<activity android:name=".ThirdActivity"> <intent-filter tools:ignore="AppLinkUrlError"> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="https" /> android:host android:port android:path android:mimeType </intent-filter> </activity>
button1.setOnClickListener { val intent = Intent(Intent.ACTION_VIEW) intent.data = Uri.parse("https://www.baidu.com") startActivity(intent) } // 打电话 val intent = Intent(Intent.ACTION_DIAL) intent.data = Uri.parse("tel:10086")
- 向Activity传数据
putExtra() getStringExtra() getIntExtra()
button1.setOnClickListener { val data = "Hello SecondActivity" val intent = Intent(this, SecondActivity::class.java) intent.putExtra("extra_data", data) startActivity(intent) } // 其他 Activity class SecondActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.second_layout) val extraData = intent.getStringExtra("extra_data") Log.d("SecondActivity", "extra data is $extraData") } }
- 返回数据给上个activity
button1.setOnClickListener { val intent = Intent(this, SecondActivity::class.java) startActivityForResult(intent, 1) // 第二个请求吗用于判断跳转来源 } 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") } } } // 跳转到的Activity class SecondActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.second_layout) // 手动返回 button2.setOnClickListener { val intent = Intent() intent.putExtra("data_return", "Hello FirstActivity") setResult(RESULT_OK, intent) // 第一个参数还可返回 RESULT_CANCELED, finish() } } // 通过返回键返回 override fun onBackPressed() { val intent = Intent() intent.putExtra("data_return", "Hello FirstActivity") setResult(RESULT_OK, intent) finish() } }
运行状态
- 完整生存期。Activity在onCreate()方法和onDestroy()方法之间所经历的就是完整生存期。一般情况下,一个Activity会在onCreate()方法中完成各种初始化操作,而在onDestroy()方法中完成释放内存的操作。
- 可见生存期。Activity在onStart()方法和onStop()方法之间所经历的就是可见生存期。在可见生存期内,Activity对于用户总是可见的,即便有可能无法和用户进行交互。我们可以通过这两个方法合理地管理那些对用户可见的资源。比如在onStart()方法中对资源进行加载,而在onStop()方法中对资源进行释放,从而保证处于停止状态的Activity不会占用过多内存。
- 前台生存期。Activity在onResume()方法和onPause()方法之间所经历的就是前台生存期。在前台生存期内,Activity总是处于运行状态,此时的Activity是可以和用户进行交互的,我们平时看到和接触最多的就是这个状态下的Activity。
后台的Activity被销毁后,返回页面时会调用onCreate再构建一次,此时会丢失临时数据
// 此处的Bundle会作为onCreate方法的参数传入
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
val tempData = "Something you just typed"
outState.putString("data_key", tempData)
}
启动模式
在AndroidManifest.xml中通过给标签指定 android:launchMode属性来选择启动模式
- standard
默认,启动后在栈顶创建,再启动时不管是否栈中存在,一定再创建一个 - singleTop
处于栈顶时不再创建,否则创建新的
<activity android:name=".FirstActivity" android:launchMode="singleTop" android:label="This is FirstActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity>
- singleTask
创建时,如果没有新的则创建;否则将栈中其上的全部销毁,使其到栈顶
<activity android:name=".FirstActivity" android:launchMode="singleTask" android:label="This is FirstActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
- singleInstance
启用一个新的返回栈来管理这个Activity(其实如果singleTask模式指定了不同的taskAffinity,也会启动一个新的返回栈)。
程序的某个Activity允许其他程序调用,这种模式下,会有一个单独的返回栈来管理这个Activity,不管是哪个应用程序来访问这个Activity,都共用同一个返回栈,也就解决了共享Activity实例的问题。
<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>
开发技巧
定位当前 Activity
创建一个BaseActivity 用于继承
open class BaseActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d("BaseActivity", javaClass.simpleName)
}
}
随时退出程序
要用一个专门的集合对所有的Activity进行管理,实现一个按键退出所有Activity
// 单例列表
object ActivityCollector {
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) {
// 注意在销毁Activity之前,我们需要先调用activity.isFinishing来判断Activity是否正在销毁中,因为Activity还可能通过按下Back键等方式被销毁
if (!activity.isFinishing) {
activity.finish()
}
}
activities.clear()
// 杀死当前进程
android.os.Process.killProcess(android.os.Process.myPid())
}
}
open class BaseActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d("BaseActivity", javaClass.simpleName)
ActivityCollector.addActivity(this)
}
override fun onDestroy() {
super.onDestroy()
ActivityCollector.removeActivity(this)
}
}
// 一个按键退出所有
button3.setOnClickListener {
ActivityCollector.finishAll()
}
启动 Activity 最佳写法
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("param1", "data1")
intent.putExtra("param2", "data2")
startActivity(intent)
上面正确,但是容易出现问题。理不清关系
class SecondActivity : BaseActivity() {
// ...
// 所有定义在companion object中的方法都可以使用类似于Java静态方法的形式调用
companion object {
fun actionStart(context: Context, data1: String, data2: String) {
val intent = Intent(context, SecondActivity::class.java)
intent.putExtra("param1", data1)
intent.putExtra("param2", data2)
context.startActivity(intent)
}
}
}
// 它的使用
button1.setOnClickListener {
SecondActivity.actionStart(this, "data1", "data2")
}
标签:val,基础,intent,Activity,Intent,android,onCreate,data From: https://www.cnblogs.com/zhh567/p/17015939.html