Android-四大组件

1. Activity

onCreate()
• 触发时机:Activity 被创建时调用,生命周期的起点。
• 用途:在此方法中进行初始化操作,比如:
• 设置布局 (setContentView)
• 初始化控件和变量
• 恢复保存的状态数据(如果存在)
onStart()
• 触发时机:Activity 从不可见变为可见时调用。
• 用途:表示 Activity 已经进入“可见状态”,但还没有出现在前台(用户还不能与之交互)。
• 一般在这里开始一些界面可见时需要的操作,比如注册广播接收器。
onResume()
• 触发时机:Activity 已经变得可见且在前台,用户可以开始与之交互。
• 用途:表示 Activity 进入了“前台活跃状态”。
• 在这里开始处理用户输入和界面更新,比如播放动画或启动传感器监听。
onPause()
• 触发时机:当 Activity 即将进入 不可交互状态,但仍然可见时调用。
• 用途:
• 用于保存用户的临时数据、状态或停止动画。
• 释放占用的资源,如暂停视频播放、保存数据等。

注意:onPause() 执行时间很短,不能在此进行耗时操作。

onStop()
• 触发时机:Activity 完全不可见时调用。
• 用途:
• 释放占用的资源,如取消广播监听、停止后台线程等。
• 一般用于持久化数据或释放大量资源。
onDestroy()
• 触发时机:Activity 被销毁时调用,这是生命周期的终点。
• 用途:用于清理资源、取消任务或解除与组件的绑定。
onRestart()
• 触发时机:Activity 从停止状态重新启动时调用。
• 用途:一般用于重新初始化数据或状态。

例如,当用户按下返回键后又重新启动 Activity,会调用 onRestart()。

Fragment 的生命周期与 Activity 密切相关,但 Fragment 生命周期的方法触发时间稍微不同。了解 Fragment 生命周期有助于你在合适的时机执行不同的任务,如初始化视图、释放资源、暂停动画等。以下是简化的 Fragment 生命周期流程:

1.  onAttach():Fragment 附加到 Activity。
2.  onCreate():Fragment 创建。
3.  onCreateView():创建视图。
4.  onActivityCreated():Activity 创建完成。
5.  onStart():Fragment 可见。
6.  onResume():Fragment 前台,用户可交互。
7.  onPause():Fragment 后台,暂停用户交互。
8.  onStop():Fragment 完全不可见。
9.  onDestroyView():销毁视图。
10. onDestroy():销毁 Fragment。
11. onDetach():解除与 Activity 的关联
2. Service

作用:

Service 是在后台运行的组件,用于执行不需要用户界面的长时间操作。Service 可以执行如播放音乐、下载文件、处理网络请求等任务,即使在应用界面不活跃或用户离开时,它也可以继续运行。

特点:

Service 在后台执行操作,不与用户直接交互。
Service 有两种类型:前台 Service(例如音乐播放器)和后台 Service(执行无界面的后台任务)。
它可以在不同的 Activity 之间共享,或者与 BroadcastReceiver 结合使用。

2种启动方式:
startService() -> onCreate() -> onStartCommand() -> service运行 -> onDestroy()
bindService() -> onCreate() -> onBind() -> 客户端绑定到Service -> unBindService() -> onUnbind() -> onDestroy()

class BoxService : Service() {

    override fun onCreate() {
        super.onCreate()
        Log.d("BoxService", "Service Created")
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.d("BoxService", "Service Started")
        return super.onStartCommand(intent, flags, startId) // 确保服务在被系统杀死后会自动重启
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d("BoxService", "Service Destroyed")
    }

    override fun onBind(intent: Intent?): IBinder? {
        // 如果不需要绑定服务,返回 null
        return null
    }
}

在定义一个上面的Service后,可以使用startService来启动和stopService来停止,它的停止和调用者没有必然联系,startService后,只要不调用stopService,就不会停止:

class BoxServiceActivity :AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_box_test)

        val btnStart = findViewById<Button>(R.id.start_btn)
        btnStart.setOnClickListener {
            Log.e("Click","start被点击了")
            val intent = Intent(this,BoxService::class.java)
            startService(intent)
        }

        val btnStop = findViewById<Button>(R.id.stop_btn)
        btnStop.setOnClickListener {
            Log.e("Click","stop被点击了")
            val intent = Intent(this,BoxService::class.java)
            stopService(intent)
        }
    }
}

使用bindService的情况,先定义一个自定的Service,需要重写onBind方法,返回一个自定义的Binder:

class BoxBindService :Service() {

    private var count = 0
    private var exit = false

    private val binder:MyBinder = MyBinder()

    inner class MyBinder : Binder() {
        fun getCount():Int {
            return count
        }
    }
    override fun onBind(p0: Intent?): IBinder {
        Log.e("BoxService", "Service onBind")
        return binder
    }

    override fun onUnbind(intent: Intent?): Boolean {
        Log.e("BoxService", "Service onUnbind")
        return super.onUnbind(intent)

    }

    override fun onCreate() {
        super.onCreate()
        Log.e("BoxService", "Service Created")

        object :Thread(){
            override fun run() {
                super.run()
                while (!exit) {
                    try {
                        sleep(1000)
                    } catch (e:InterruptedException) {
                        e.printStackTrace()
                    }
                    count ++
                }
            }
        }.start()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.e("BoxService", "Service Started")
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.e("BoxService", "Service Destroyed")
    }
}

在Activity中来bindService后,可以随时使用自定义Binder的方法,来获取计数,也可以调用自定义Binder的stopCounter方法来停止计数,在Activity销毁的时候需要调用unbindService来取消绑定,如果前面已经调用过unbindService,这时候会报错Service not registered,所以声明一个变量来标识有没有绑定Service,在Activity销毁的时候判断下,如果是绑定状态则需要调用unbindService来取消绑定,也就是bindServiceunbindService是需要成对出现。

class BoxServiceActivity :AppCompatActivity() {

    private var myBinder :BoxBindService.MyBinder? = null
    private var connection :ServiceConnection? = null
    private var isBind = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_box_test)

        connection = object :ServiceConnection {
            override fun onServiceConnected(p0: ComponentName?, p1: IBinder?) {
                Log.e("BoxService", "Service onServiceConnected")
                myBinder = p1 as BoxBindService.MyBinder
                isBind = true
            }
            override fun onServiceDisconnected(p0: ComponentName?) {
                Log.e("BoxService", "Service onServiceDisconnected")
                isBind = false
            }
        }

        val intent = Intent(this,BoxBindService::class.java)
        bindService(intent, connection as ServiceConnection, Context.BIND_AUTO_CREATE)

        val btnStart = findViewById<Button>(R.id.start_btn)
        val btnStop = findViewById<Button>(R.id.stop_btn)
        btnStart.setOnClickListener {
            val num = myBinder!!.getCount()
            Log.e("BoxService", "Service 拿到数字:${num}")
        }
        btnStop.setOnClickListener {
            unbindService(connection!!)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        if (isBind) {
            unbindService(connection!!)
        }
    }
}
3. BroadcastReceiver

BroadcastReceiver 是 Android 中四大组件之一,它用于接收系统或应用程序广播的消息,并对广播进行响应。通过广播,应用程序可以向其他应用或系统组件发送消息,也可以接收来自系统或其他应用的消息。

  1. 广播的基本概念

广播是一种传递消息的机制,可以在不同的应用之间或应用内部不同的组件之间传递信息。Android 系统提供了许多内建的广播,如屏幕关闭、网络状态变化、系统启动等。应用也可以自定义广播,向其他应用发送消息。

  1. 广播接收器的工作原理

BroadcastReceiver 是一个用于接收广播并处理的组件。当系统或应用发送一个广播时,符合接收条件的 BroadcastReceiver 会被触发,并通过回调方法处理广播。

尝试定义一个网络监听的广播:

class BoxBroadcastReceiver : BroadcastReceiver() {
    override fun onReceive(p0: Context?, p1: Intent?) {
        val action = p1?.action ?:return
        if (action == ConnectivityManager.CONNECTIVITY_ACTION) {
            val connectivityManager:ConnectivityManager = p0?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            val info = connectivityManager.activeNetworkInfo
            if (info != null && info.isAvailable ) {
                val typeName = info.typeName
                Toast.makeText(p0,"当前网络: $typeName", Toast.LENGTH_LONG).show()
            }
            else {
                Toast.makeText(p0,"当前无网络", Toast.LENGTH_LONG).show()
            }
        }
    }
}

在Activity中来注册这个广播:

receiver = BoxBroadcastReceiver()
val intentFilter = IntentFilter()
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION)
registerReceiver(receiver,intentFilter)

注册广播后,要在适当的位置进行取消注册unregisterReceiver(receiver),在平常的是使用中,基本上应用内的广播就可以满足要求,效率会更好,安全性也更高,注册应用内的广播使用LocalBroadcastManager.getInstance(this).registerReceiver(receiver,intentFilter),取消注册应用内的广播使用LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver)

4. ContentProvider

ContentProvider 主要用于在应用程序之间共享数据。它为不同的应用提供了一种一致的接口来访问和操作数据,而不需要直接访问底层的存储机制。
ContentProvider 的功能类似于一个数据库的接口,通过统一的 ContentResolver 和 URI(统一资源标识符)机制,来管理对数据的访问。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354

推荐阅读更多精彩内容