安卓 Activity 详解 —《第一行代码》学习笔记 02

Activity(活动)

Activity基本点:
  • android: id -> 给当前的元素定义一个唯一的标识符 .
  • XML引用一个 id -> @id/id_name
  • XML定义一个 id ->. @+id/id_name
  • android: layout_width -> 指定当前元素的宽度 . match_parent 表示令当前元素和父元素同宽 .
  • android: layout_height -> 指定当前元素的高度 . wrap_content 表示当前元素的高度刚好包含其中的内容 .
  • android: text -> 指定了元素中显示的文本内容 .
  • setContentView( )方法:给当前的 Activity 加载一个布局 .
  • R.layout.XXX -> 引用布局文件,得到 XXX.xml 布局的 id .
注册声明:
  • 注册声明 置于 标签中,通过 标签对 Activity 进行注册.
  • android: name -> 指定具体注册哪一个 Activity .
  • .FirstActivity -> com.example.activitytest.FirstActivity 的缩写.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.activitytest">

    <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"
            android:label="This is FirstActivity.">
						<!-- !!!! MAIN / LAUNCHER 声明 . label 设置标题栏内容 -->
						<intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
Toast —— 提醒方式:
  • findViewById( ) -> 获取在布局文件中定义的元素 . 括号中放置 android: id 属性指定的值 . 返回一个继承自 View 的泛型对象 .

  • Kotlin 中需要显式声明控件类型,如 Button、TextView .

  • setOnClickListener( ) -> 使用该方法为按钮注册一个监听器 . / 弹出 Toast 功能需要在 onClick( ) 方法中编写 .

  • makeTest( ) -> 静态方法,创造出一个 Toast 对象,然后调用 show( ) 显示 .

三个参数:
1. Context 对象 —— Activity 本身可用 this 替代 .
2. Toast 显示的内容.
3. Toast 显示的时长. LENGTH_SHORT/LONG

  • 引用插件,省去调用 findViewById( ) 方法 .
button1.setOnClickListener {
            Toast.makeText(this, "You clicked Button 1", Toast.LENGTH_LONG).show()
/*
val button1: Button = findViewById(R.id.button1)
button1.setOnClickListener {
		Toast.makeText(this, "You clicked Button 1", Toast.LENGTH_SHORT).show()
        */
}
在 Activity 中使用 Menu:
  • Menu Resource File -> main.xml
  • android: id -> 唯一的标识符 . android: title -> 指定菜单项的名称 .
  • 在 main.xml 中创建菜单项,回到 FirstActivity 中重写 onCreateOptionsMenu( ) 方法 .
  • Kotlin 语法糖:menuInflater 实际上调用了父类的 getMenuInflater( ) 方法,从而得到一个 MenuInflater 对象,接着调用 inflate( ) 方法
  • Inflate( ) 参数:1. 创建菜单的资源文件 . 2. 目标 Menu 对象 .
  • onOptionsItemSelected( ) 方法中,通过调用 item.itemId 判断点击的菜单项 . / 背后调用 getItemId( ) 方法 .
    <item
        android:id="@+id/add_item"
        android:title="Add"/>
    <item
        android:id="@+id/remove_item"
        android:title="Remove"/>

// 重写 onCreateOptionsMenu() 方法
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.main, menu)
        return true    // 创建的菜单显示出来.
    }

// 定义菜单响应事件.   重写 onOptionsItemSelected() 方法
override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.add_item -> Toast.makeText(this, "You clicked Add",
                                Toast.LENGTH_SHORT).show()
            R.id.remove_item -> Toast.makeText(this, "You clicked Remove",
                                Toast.LENGTH_SHORT).show()
        }
        return true
    }

// 销毁 Activity
button1.setOnClickListener {
  finish()
}

使用 Intent 在 Activity 之间穿梭:

Intent:
  • Android 程序中各组件之间进行交互 . 指明当前组件要执行的动作 / 组件之间传递数据 .
  • 用于 启动Activity 、 启动Service 、 发送广播 .
// 构造函数的重载:
Intent(Content packageContext, Class<?>cls)
// 参数1 — 提供启动 Activity 的上下文.
// 参数2 - Class 用于指定想要启动的目标 Activity.
使用 Activity — startActivity() 方法 — 接收 Intent 参数.
startActivity(intent)

// 隐式 Intent:
val intent = Intent("com.example.activitytest.ACTION_START")
intent.addCategory("com.example.activitytest.MY_CATEGORY")  // - 程序崩溃 - xml 中需要声明.
startActivity(intent)

// 多个程序间的功能共享:—— 访问百度
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("https://www.baidu.com")
startActivity(intent)
// Uri.parse() 方法 —— 将一个网址字符串解析成一个 Uri对象.
// setData() 方法 —— 将 Uri对象 传递. 
// 接收 Uri对象,用于指定当前 Intent正在操作的数据,通常以字符串形式传入 Uri.parse()方法中解析.

// 多个程序之间的功能共享:—— 调用系统拨号界面
val intent = Intent(Intent.ACTION_DIAL)
intent.data = Uri.parse("tel:10086")
startActivity(intent)
  • android: scheme - 指定数据的协议部分 . https

  • android: host - 指定数据的主机名部分 . // www.baidu.com

  • android: port - 指定数据的端口部分 . (主机名之后)

  • android: path - 指定主机名和端口之后的部分 . // 域名之后的内容

  • android: mimeType - 指定可以处理的数据类型,允许使用通配符的方式进行指定 .

    只要指定 android: scheme 为 https,就可以响应所有 https协议 的 Intent 了.

向下一个 Activity 传递数据:
  • putExtra( ) - 启动 Activity时 ,传递数据 . 接收两个参数 — 1. 键(Intent 中取值) 2. 传递的数据
// 在 FirstActivity 中传递数据.
val data = "Hello SecondActivity."
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("extra_data", data)
startActivity(intent) // 显式 Intent
// 在 SecondActivity 中提取数据.
返回数据给上一个 Activity
  • startActivityForResult( ) - 启动 Activity. 参数一:Intent,参数二:请求码(在回调中判断数据的来源).

  • setResult( ) - 专门用于向上一个 Activity 返回数据 .

    参数一:向上一个 Activity 返回处理结果(RESULT_OK / RESULT_CANCELED)

    参数二:把带有数据的 Intent 传递回去. 最后调用 finish( ) 销毁当前 Activity.

// FirstActivity
val data = "Hello SecondActivity."
val intent = Intent(this, SecondActivity::class.java)
//            intent.putExtra("extra_data", data)
//            startActivity(intent)
startActivityForResult(intent, 1)

// SecondActivity
button2.setOnClickListener{
		val intent = Intent()
    intent.putExtra("data_return", "Hello FirstActivity")
    setResult(RESULT_OK, intent)
    finish()
}

// 重写方法 onActivityResult()
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")
            }
        }
    }

// 重写方法 onBackPressed()
override fun onBackPressed() {
        val intent = Intent()
        intent.putExtra("data_return", "Hello FirstActivity")
        setResult(RESULT_OK, intent)
        finish()
}

  • onActivityResult( ) - 带有三个参数.

    参数一:requestCode - 即在我们启动 Activity 时传入的请求码 .

    参数二:resultCode - 即在我们返回数据时传入的处理结果 .

    参数三:data - 即携带着返回数据的 Intent .

    返回数据操作:通过检查 requestCode 的值来判断数据来源,通过 resultCode 的值来判断处理结果是否成功,从 data 取值并且打印

  • onBackPressed( ) - 按下 Back 键时,同样返回数据 .

Activity 的生命周期:

返回栈
  • 任务(Task)管理 Activity,一个任务就是一组存放在栈里的 Activity 集合 —— 返回栈(Back Stack)- 后进先出
  • 系统总是显示处于栈顶的 Activity 给用户 . Back键 / finish( ) 方法销毁一个 Activity .
Activity 状态
  • 运行状态 - 当一个 Activity 处于返回栈的栈顶时,处于运行状态 .
  • 暂停状态 - 当一个 Activity 不再处于栈顶位置,但仍然可见时,处于暂停状态 .
  • 停止状态 - 当一个 Activity 不再处于栈顶位置,并且完全不可见时,就进入停止状态 .
  • 销毁状态 - 一个 Activity 从返回栈移除后就变成了销毁状态 .

Activity 生存期

  • onRestart( ) - Activity 由停止状态变为运行状态之前调用 .
  • 完整生存期
    • onCreate( ) - 在 Activity 第一次创建时调用 . —— 初始化操作
    • onDestory( ) - 在 Activity 被销毁之前调用 . —— 释放内存
  • 可见生存期
    • onStart( ) - 在 Activity 由不可见变为可见的时候调用 . ——加载资源
    • onStop( ) - 在 Activity 完全不可见的时候调用 . —— 释放资源
  • 前台生存期 - 运行状态
    • onResume( ) - 在 Activity 准备好和用户进行交互的时候调用 .
    • onPause( ) - 在系统准备去启动或恢复另一个 Activity 的时候调用 .

体验 Activity 的生命周期

  • Android:theme - 用于给当前 Activity 指定主题 .

    @style/Theme.AppCompat.Dialog 使用对话框式的主题 .

  • Log.d(tag, “xxx”) - 打印日志,输出了一句话 .

// MainActivity 配置
class MainActivity : AppCompatActivity() {

    private val tag = "MainActivity"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d(tag, "onCreate")
        setContentView(R.layout.activity_main)
        if (savedInstanceState != null) {
            val tempData = savedInstanceState.getString("data_key")
            if (tempData != null) {
                Log.d(tag, tempData)
            }
        }
        startNormalActivity.setOnClickListener{
            val intent = Intent(this, NormalActivity::class.java)
            startActivity(intent)
        }
        startDialogActivity.setOnClickListener{
            val intent = Intent(this, DialogActivity::class.java)
            startActivity(intent)
        }
    }

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

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

    override fun onStop() {
        super.onStop()
        Log.d(tag,"onStop")
    }

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

    override fun onRestart() {
        super.onRestart()
        Log.d(tag,"onRestart")
    }
}
  • 按钮一:启动 NormalActivity —— 打印 onPause 、onStop

  • 按下 Back 键:返回 MainActivity —— 打印 onRestart 、onStart 、onResume

  • 按钮二:启动 DialogActivity —— 打印 onPause

  • 按下 Back 键:返回 MainActivity —— 打印 onResume

  • 按下 Back 键:退出程序 —— 打印 onPause、onStop、onDestroy,最终销毁 MainActivity

  • onSaveInstanceState( ) - 保证在 Activity 被回收之前一定会被调用 . 携带 Bundle 类型参数

  • putString( ) - 保存字符串 . putInt( ) - 保存整型数据 .

  • 每个保存方法传入两个参数。参数一:键 参数二:用于后面从 Bundle 中取值,即真正保存的内容 .

Activity 的启动模式:通过 标签指定 android:launchMode 属性选择启动模式

standard(默认)
  • 每次启动都会创建一个该 Activity 的新实例 .
singleTop
  • 在启动 Activity 时如果发现返回栈的栈顶已经是该 Activity,则认为可以直接使用它,不会再创建新的 Activity 实例 .
singleTask
  • 在启动 Activity 时,系统首先会在返回栈中检查是否存在该 Activity 的实例,如果发现已经存在则直接使用该实例,并把在这个Activity 之上的所有其他 Activity 统统出栈,如果未发现就会创建一个新的 Activity 实例 .
singleInstance
  • 启用一个新的返回栈来管理这个 Activity . 实现程序之间的共享,其它程序访问这个 Activity 时,共用一个返回栈 .

Activity 的最佳实践:

知晓当前是在哪一个 Activity
  • javaClass - 表示获取当前实例的 Class 对象,相当于在 Java 中调用 getClass( ) 方法 .
  • BaseActivity::class.java - 表示获取 BaseActivity 类的 Class 对象,相当于在 Java 中调用 BaseActivity.class
  • 调用 simpleName 获取当前实例的类名 .
open class BaseActivity : AppCompatActivity(){
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("BaseActivity", javaClass.simpleName)
    }
}
// 修改 FirstActivity、SecondActivity、ThirdActivity 继承结构,使其继承自 BaseActivity
随时随地退出程序
  • 用一个专门的集合对所有 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){
            if (!activity.isFinishing){
                activity.finish()
            }
        }
        activities.clear()
    }
}
  • ArrayList - 暂存 Activity addActivity( ) - 用于向 ArrayList 中添加 Activity .
  • removeActivity( ) - 用于从 ArrayList 中移除 Activity . finishAll( ) - 用于将 ArrayList 中存储的 Activity 全部销毁 .
  • activity.isFinishing 判断 Activity 是否正在销毁中 . Finish( ) - 销毁 Activity
// 杀掉进程的代码
android.os.Process.killProcess(android.os.Process.myPid())
// killProcess() 用于杀掉一个进程,它接收一个进程 id参数,我们可以通过 myPid() 方法来获得当前程序的进程 id
// killProcess() 方法只能用于杀掉当前程序的进程,不能杀掉其他程序.
启动 Activity 的最佳写法
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)
  }
}
// 语法结构 companion object
// 定义 actionStart() 方法 —— 构建 Intent —— actionStart() 方法完成参数传递

// 简化了启动 Activity 的代码 —— 启动 SecondActivity
button1.setOnClickListener {
  SecondActivity.actionStart(this, "data1", "data2")
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xmurphymurphy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值