首页 > 编程语言 >Android第一行代码——快速入门 Kotlin 编程(3.6 Activity 的最佳实践)

Android第一行代码——快速入门 Kotlin 编程(3.6 Activity 的最佳实践)

时间:2024-03-20 17:32:02浏览次数:20  
标签:SecondActivity BaseActivity Kotlin 3.6 Activity fun onCreate 方法

目录

3.6        Activity 的最佳实践

3.6.1        知晓当前是在哪一个 Activity

3.6.2        随时随地退出程序

 3.6.3        启动 Activity 的最佳写法


3.6        Activity 的最佳实践

        关于 Activity ,你已经掌握了非常多的知识,不过恐怕离能够完全灵活运用还有一段距离。虽然知识点只有这么多,但运用的技巧却是多种多样的。所以,在这里我准备教你几种关于Activity 的最佳实践技巧,这些技巧在你以后的开发工作当中将会非常有用。

3.6.1        知晓当前是在哪一个 Activity

        这个技巧将教会你如何根据程序当前的界面就能判断出这是哪一个 Activity 。可能你会觉得挺纳闷的,我自己写的代码怎么会不知道这是哪一个 Activity 呢?然而现实情况是,在你进入一家公 司之后,更有可能的是接手一份别人写的代码,因为你刚进公司就正好有一个新项目启动的概率并不高。阅读别人的代码时有一个很头疼的问题,就是当你需要在某个界面上修改一些非常简单的东西时,却半天找不到这个界面对应的 Activity 是哪一个。学会了本节的技巧之后,这对你来说就再也不是难题了。

        我们还是在 ActivityTest 项目的基础上修改,首先需要新建一个 BaseActivity 类。右击 com.example.activitytest 包→New→Kotlin F ile/Class ,在弹出的窗口中输入 BaseActivity ,创建类型选择 Class ,如 图3.43 所示。

图3.43        创建 BaseActivity 类

        注意,这里的 BaseActivity 和普通 Activity 的创建方式并不一样,因为我们不需要让 BaseActivity 在 AndroidManifest.xml 中注册,所以选择创建一个普通的 Kotlin 类就可以 了。然后让 BaseActivity 继承自 AppCompatActivity,并重写 onCreate() 方法,如下所示:

open class BaseActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("BaseActivity", javaClass.simpleName)
    }
}

        我们在 onCreate() 方法中加了一行日志,用于打印当前实例的类名。这里我要额外说明一 下,Kotlin 中的 javaClass 表示获取当前实例的 Class 对象,相当于在Java 中调用 getClass()方法;而 Kotlin 中的 BaseActivity::class.java 表示获取 BaseActivity 类的 Class 对象,相当于在Java 中调用 BaseActivity.class。在上述代码中,我们先是获取了当前实例的 Class 对象,然后再调用 simpleName 获取当前实例的类名。

        接下来我们需要让 BaseActivity 成为 ActivityTest 项目中所有 Activity 的父类,为了使 BaseActivity 可以被继承,我已经提前在类名的前面加上了open 关键字。然后修改 FirstActivity 、SecondA ctivity 和 ThirdActivity 的继承结构,让它们不再继承自 AppCompatActivity,而是继承自 BaseActivity。而由于 BaseActivity 又是继承自 AppCompatActivity 的,所以项目中所有 Activity 的现有功能并不受影响,它们仍然继承了 Activity 中的所有特性。

        现在重新运行程序,然后通过点击按钮分别进入FirstActivity 、SecondA ctivity 和 ThirdActivity 的界面,这时观察 Logcat 中的打印信息,如 图3.44 所示。

图3.44        BaseActivity 中的打印日志

        现在每当我们进入一个 Activity 的界面,该 Activity 的类名就会被打印出来,这样我们就可以时刻知晓当前界面对应的是哪一个 Activity 了。

小贴士:

javaClass 表示获取当前实例的 Class 对象

3.6.2        随时随地退出程序

        如果目前你手机的界面还停留在 ThirdActivity ,你会发现当前想退出程序是非常不方便的,需要连按 3 次 Back 键才行。按 Home 键只是把程序挂起,并没有退出程序。如果我们的程序需要 注销或者退出的功能该怎么办呢?看来要有一个随时随地都能退出程序的方案才行。

        其实解决思路也很简单,只需要用一个专门的集合对所有的 Activity 进行管理就可以了。下面我们就来实现一下。

        新建一个单例类 ActivityCollector 作为 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()
    }
}

        这里使用了单例类,是因为全局只需要一个 Activity 集合。在集合中,我们通过一个 ArrayList 来暂存 Activity ,然后提供了一个 addActivity() 方法,用于向 ArrayList 中添加 Activity;提供了一个 removeActivity() 方法,用于从 ArrayList 中移除 Activity ;最后提供了一个 finishAll() 方法,用于将 ArrayList 中存储的 Activity 全部销毁。注意在销毁 Activity 之前,我们需要先调用 activity.isFinishing 来判断 Activity 是否正在销毁中,因为 Activity 还可能通过按下Back 键等方式被销毁,如果该 Activity 没有正在销毁中,我们再去调用它的 finish() 方法来销毁它。

        接下来修改 BaseActivity 中的代码,如下所示:

open class BaseActivity : AppCompatActivity() {
//    随时随地退出程序
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("BaseActivity", javaClass.simpleName)
        ActivityCollector.addActivity(this)
    }

//  onDestroy  这个方法在Activity 被销毁之前调用,之后Activity 的状态将变为销毁状态。
    override fun onDestroy() {
        super.onDestroy()
        ActivityCollector.removeActivity(this)
    }
}

        在 BaseActivity onCreate() 方法中调用了 ActivityCollector addActivity() 方法,表明将当前正在创建的 Activity 添加到集合里。然后在 BaseActivity 中重写 onDestroy() 方法,并调用了 ActivityCollector removeActivity() 方法,表明从集合里移除一个马上要销毁的 Activity 。

        从此以后,不管你想在什么地方退出程序,只需要调用 ActivityCollector.finishAll() 方法就可以了。例如在 ThirdActivity 界面想通过点击按钮直接退出程序,只需将代码改成如下形式:

class ThirdActivity : BaseActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("ThirdActivity", "Task id is $taskId ")
        setContentView(R.layout.third_layout)
        button3.setOnClickListener {
            ActivityCollector.finishAll()
        }
    }

}

        当然你还可以在销毁所有 Activity 的代码后面再加上杀掉当前进程的代码,以保证程序完全退 出,杀掉进程的代码如下所示:

class ThirdActivity : BaseActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("ThirdActivity", "Task id is $taskId ")
        setContentView(R.layout.third_layout)
        button3.setOnClickListener {
            ActivityCollector.finishAll()
            //杀掉当前进程
            android.os.Process.killProcess(android.os.Process.myPid())
        }
    }
}

        killProcess()方法用于杀掉一个进程,它接收一个进程 id 参数,我们可以通过 myPid() 方法来获得当前程序的进程 id。需要注意的是,killProcess()方法只能用于杀掉当前程序的进程,不能用于杀掉其他程序。

小贴士:

addActivity()方法,用于向 ArrayList 中添加 Activity;

removeActivity() 方法,用于从 ArrayList 中移除 Activity;

finishAll() 方法,用于将 ArrayList 中存储的 Activity 全部销毁

activity.isFinishing 来判断 Activity 是否正在销毁中

 killProcess()方法用于杀掉杀掉当前程序的进程,它接收一个进程 id 参数

myPid() 方法来获得当前程序的进程 id

 3.6.3        启动 Activity 的最佳写法

        启动 Activity 的方法相信你已经非常熟悉了,首先通过 Intent 构建出当前的“意图”,然后调用 startActivity()  startActivityForResult() 方法将 Activity 启动起来,如果有数据需要在 Activity 之间传递,也可以借助 Intent 来完成。

        假设 SecondActivity 中需要用到两个非常重要的字符串参数,在启动 SecondActivity 的时候必须传递过来,那么我们很容易会写出如下代码:

val intent = Intent(this, SecondActivity::class.java) 
intent.putExtra("param1", "data1") 
intent.putExtra("param2", "data2") 
startActivity(intent) 

        虽然这样写是完全正确的,但是在真正的项目开发中经常会出现对接的问题。比如 SecondActivity 并不是由你开发的,但现在你负责开发的部分需要启动 SecondActivity ,而你却不清楚启动 SecondActivity 需要传递哪些数据。这时无非就有两个办法:一个是你自己去阅读SecondActivity 中的代码,另一个是询问负责编写 SecondActivity 的同事。你会不会觉得很麻烦呢?其实只需要换一种写法,就可以轻松解决上面的窘境。

        修改 SecondActivity 中的代码,如下所示:

class SecondActivity : BaseActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("SecondActivity","Task id is $taskId")
        setContentView(R.layout.second_layout)
        button2.setOnClickListener {
            val intent = Intent( this,ThirdActivity::class.java)
            startActivity(intent)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d("SecondActivity", "onDestroy: singleTask启动模式,这个方法在Activity被销毁之前调用")
    }

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

//    启动 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,并在 companion object 中定义 了一个 actionStart() 方法。之所以要这样写,是因为 Kotlin 规定,所有定义在 companion object中的方法都可以使用类似于Java 静态方法的形式调用。关于 companion object 的更多内容,我会在本章的 Kotlin 课堂中进行讲解。

        接下来我们重点看 actionStart() 方法,在这个方法中完成了 Intent 的构建,另外所有 SecondActivity 中需要的数据都是通过 actionStart() 方法的参数传递过来的,然后把它们存储到Intent 中,最后调用 startActivity() 方法启动 SecondActivity 。

        这样写的好处在哪里呢?最重要的一点就是一目了然,SecondActivity 所需要的数据在方法参 数中全部体现出来了,这样即使不用阅读 SecondActivity 中的代码,不去询问负责编写 SecondActivity 的同事,你也可以非常清晰地知道启动 SecondActivity 需要传递哪些数据。另外,这样写还简化了启动 Activity 的代码,现在只需要一行代码就可以启动 SecondActivity , 如下所示:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("FirstActivity", "Task id is $taskId")
        setContentView(R.layout.first_layout)
        button1.setOnClickListener {
            //启动 Activity 的最佳写法
          SecondActivity.actionStart(this,"data1","data2")
        }
    }

        养成一个良好的习惯,给你编写的每个 Activity 都添加类似的启动方法,这样不仅可以让启动 Activity 变得非常简单,还可以节省不少你同事过来询问你的时间。

标签:SecondActivity,BaseActivity,Kotlin,3.6,Activity,fun,onCreate,方法
From: https://blog.csdn.net/fhbxts/article/details/136877152

相关文章

  • android App启动流程三-Activity启动流程
    上一篇我们介绍了从App的进程创建到Application启动执行,今天我们继续深入学习一下,Activity的启动流程。realStartActivityLocked我们接着上一篇,从ActivityTaskManagerService.attachApplication函数看起,最终发现会执行到ActivityTaskSupervisor.realStartActivityLocked方法......
  • Kotlin 协程基础使用学习
    原文:Kotlin协程基础使用学习-Stars-One的杂货小窝本篇阅读可能需要以下知识,否则可能阅读会有些困难客户端开发基础(Android开发或JavaFx开发)Java多线程基础kotlin基础本文尽量以使用为主,以代码为辅讲解,不提及过深协程底层代码逻辑,仅做一个基础入门来快速上手学习......
  • Android第一行代码——快速入门 Kotlin 编程(2.5 面向对象编程)
    目录2.5    面向对象编程2.5.1    类与对象2.5.2    继承与构造函数2.5.3    接口2.5.4    数据类与单列类2.5    面向对象编程        和很多现代高级语言一样,Kotlin也是面向对象的,因此理解什么是面向对......
  • 3.6 设置服务器来电后自动开机和设置服务定时开机
    3.6设置服务器来电后自动开机3.7设置服务定时开机 ......
  • 太久没用Android studio出现AppCompatActivity爆红无法识别
    AndroidStudio中找不到AppCompatActivity一直报红,且xml中的布局控件也在报红处理方法_appcompatactivity找不到-CSDN博客 解决办法:打开file--projectstructure,点开dependecies,点击添加,输入com.android.support:appcompat-v7添加即可  然后就好了/ ......
  • 【ChatGPT】JeecgBoot v3.6.3 AI版本发布,企业级低代码平台
    项目介绍JeecgBoot是一款企业级的低代码平台!前后端分离架构SpringBoot2.x,SpringCloud,AntDesign&Vue3,Mybatis-plus,Shiro,JWT支持微服务。强大的代码生成器让前后端代码一键生成!JeecgBoot引领低代码开发模式(OnlineCoding->代码生成->手工MERGE),帮助解决Java项目70%的重复......
  • 安卓开发学习-向上一个Activity返回数据
    发送请求页面点击查看代码packagecom.android.response;importandroid.content.Intent;importandroid.os.Bundle;importandroid.widget.Button;importandroid.widget.TextView;importandroidx.activity.result.ActivityResultLauncher;importandroidx.activity.......
  • macOS Ventura 13.6.5 (22G621) 正式版发布,ISO、IPSW、PKG 下载 (安全更新)
    macOSVentura13.6.5(22G621)正式版发布,ISO、IPSW、PKG下载(安全更新)3月8日凌晨,macOSSonoma14.4发布,同时带来了macOSVentru13.6.5和macOSMonterey12.7.4安全更新。macOSVentura13.6及更新版本,如无特殊说明皆为安全更新,不再赘述。请访问原文链接:https://......
  • macOS Ventura 13.6.5 (22G621) Boot ISO 原版可引导镜像下载
    macOSVentura13.6.5(22G621)BootISO原版可引导镜像下载3月8日凌晨,macOSSonoma14.4发布,同时带来了macOSVentru13.6.5和macOSMonterey12.7.4安全更新。macOSVentura13.6及更新版本,如无特殊说明皆为安全更新,不再赘述。本站下载的macOS软件包,既可以拖拽到......
  • Activity 流程模型导入导出-activity流程模型导入导出
    环境版本springboot:2.5.6activity:5.22.0导出@RequestMapping("/exportModelXml")publicvoidexportModelXml(HttpServletResponseresponse,@RequestParamStringmodelId)throwsIOException{Modelmodel=repositoryService.getMode......