Android基础知识——四大组件

[复制链接]
lihao0522 发表于 2023-10-27 01:41:22|来自:湖北 | 显示全部楼层 |阅读模式
一、Android基础知识

1、Android介绍

Android是一种基于Linux是自由及开放源代码的操作系统,Android分为四个层,从高层到底层分别是应用程序层、应用程序框架层、系统运行库层和Linux内核层
2、Android四大组件

Android有四大基本组件:Activity、Service服务、BroadcastReceiver广播接收器、Content Provider内容提供者
二、Activity

1、Activity介绍

Activity是一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务
Activity中所有操作都与用户密切相关,是一个负责与用户交互的组件,可以通过setContentView(View)来显示指定控件
在一个android应用中,一个Activity通常就是一个单独的屏幕,它上面可以显示一些控件也可以监听并处理用户的事件做出响应。Activity之间通过Intent进行通信
2、Activity四种基本状态

(1)Active/Running
一个新 Activity 启动入栈后,它显示在屏幕最前端,处于栈的最顶端(Activity栈顶),此时它处于可见并可和用户交互的激活状态,叫做活动状态或者运行状态
(2)Paused
当 Activity失去焦点, 被一个新的非全屏的Activity 或者一个透明的Activity 被放置在栈顶,此时的状态叫做暂停状态(Paused)。此时它依然与窗口管理器保持连接,Activity依然保持活力(保持所有的状态,成员信息,和窗口管理器保持连接),但是在系统内存极端低下的时候将被强行终止掉。所以它依旧可见,但已经失去了焦点故不可与用户进行交互。
(3)Stopped
如果一个Activity被另外的Activity完全覆盖掉,叫做停止状态(Stopped)。它依然保持所有状态和成员信息,但是它不再可见,所以它的窗口被隐藏,当系统内存需要被用在其他地方的时候,Stopped的Activity将被强行终止掉。
(4)Killed
如果一个Activity是Paused或者Stopped状态,系统可以将该Activity从内存中删除,Android系统采用两种方式进行删除,要么要求该Activity结束,要么直接终止它的进程。当该Activity再次显示给用户时,它必须重新开始和重置前面的状态。
3、Activity状态转换

当一个 Activity 实例被创建、销毁或者启动另外一个 Activity 时,它在这四种状态之间进行转换,这种转换的发生依赖于用户程序的动作



Activity状态转换图

如上图所示,Android程序员可以决定一个 Activity 的“生”,但不能决定它的“死”,也就是说程序员可以启动一个 Activity,但是却不能手动的“结束”一个 Activity
当你调用Activty.finish()方法时,结果和用户按下 BACK 键一样:告诉 Activity Manager 该 Activity 实例完成了相应的工作,可以被“回收”。随后 Activity Manager 激活处于栈第二层的 Activity 并重新入栈,同时原 Activity 被压入到栈的第二层,从 Active 状态转到 Paused 状态
例如:从 Activity1 中启动了 Activity2,则当前处于栈顶端的是 Activity2,第二层是 Activity1,当我们调用Activity2.finish()方法时,Activity Manager 重新激活 Activity1 并入栈,Activity2 从 Active状态转换Stoped 状态,Activity1.onActivityResult(int requestCode, int resultCode, Intent data)方法被执行,Activity2 返回的数据通过data参数返回给 Activity1
4、Activity栈

Android 是通过一种 Activity 栈的方式来管理 Activity 的,一个 Activity 的实例的状态决定它在栈中的位置。处于前台的 Activity 总是在栈的顶端,当前台的 Activity 因为异常或其它原因被销毁时,处于栈第二层的 Activity 将被激活,上浮到栈顶。当新的 Activity 启动入栈时,原 Activity 会被压入到栈的第二层。一个 Activity 在栈中的位置变化反映了它在不同状态间的转换。Activity 的状态与它在栈中的位置关系如下图所示



Activity 的状态与它在栈中的位置关系

如上图所示,除了最顶层即处在 Active 状态的 Activity 外,其它的 Activity 都有可能在系统内存不足时被回收,一个 Activity 的实例越是处在栈的底层,它被系统回收的可能性越大。系统负责管理栈中 Activity 的实例,它根据 Activity 所处的状态来改变其在栈中的位置
5、方法通知

下面的图显示了Activity的重要状态转换,矩形框表明Activity在状态转换之间的回调接口,开发人员可以重载实现以便执行相关代码,带有颜色的椭圆形表明Activity所处的状态。


在上图中,Activity有三个关键的循环:
1. 整个的生命周期,从onCreate(Bundle)开始到onDestroy()结束。Activity在onCreate()中设置所有的“全局”状态,在onDestory()中释放所有的资源
例如:某个Activity有一个在后台运行的线程,用于从网络下载数据,则该Activity可以在onCreate()中创建线程,在onDestory()中停止线程
2. 可见的生命周期,从onStart()开始到onStop()结束。在这段时间,可以看到Activity在屏幕上,尽管有可能不在前台,不能和用户交互。在这两个接口之间,需要保持显示给用户的UI数据和资源等
例如:可以在onStart()中注册一个IntentReceiver来监听数据变化导致UI的变动,当不再需要显示时候,可以在onStop()中注销它。onStart(),onStop()都可以被多次调用,因为Activity随时可以在可见和隐藏之间转换。
3. 前台的生命周期,从onResume()开始到onPause()结束。在这段时间里,该Activity处于所有 Activity的最前面,和用户进行交互。Activity可以经常性地在resumed和paused状态之间切换
例如:当设备准备休眠时、当一个 Activity处理结果被分发时、当一个新的Intent被分发时。所以在这些接口方法中的代码应该属于非常轻量级的
6、Activity生命周期

(1)onCreate():在Activity创建时调用,通常做一些初始化设置,不可见,只在Activity创建时执行一次
(2)onStart():在Activity即将可见时调用,可见,在Activity中多次调用,不在前台,不可交互,初始化工作
(3)onResume():在Activity获取焦点开始与用户交互时调用,在前台,开启动画和独占设备
(4)onPause():在当前Activity被其它Activity覆盖或锁屏时调用,可见,程序状态的保存,独占设备和动画的关闭,以及一些数据的保存最好在onPause中进行,但不能太耗时
(5)onStop():在Activity对用户不可见时调用,不可见,其对象还在内存中,系统内存不足时可能不会执行onStop()方法
(6)onDestroy():在Activity销毁时调用
(7)onRestart():在Activity从停止状态再次启动时调用
三、Service

1、Service介绍

Service是android系统的四大组件之一,是一种长生命周期的,没有可视化界面,运行于后台的一种服务程序
2、启动方式

(1)Started Service
被开启的service通过其他组件调用startService()被创建,这种service可以无限地运行下去,必须调用stopSelf()方法或者其他组件调用stopService()方法来停止它,当service被停止时,系统会销毁它
(2)Bounded Service
被绑定的service是当其他组件(一个客户)调用bindService()来创建的,客户可以通过一个IBinder接口和service进行通信,客户可以通过unbindService()方法来关闭这种连接,一个service可以同时和多个客户绑定,当多个客户都解除绑定之后,系统会销毁service
3、Service生命周期

(1)service整体的生命时间是从onCreate()被调用开始,到onDestroy()方法返回为止。和activity一样,service在onCreate()中进行它的初始化工作,在onDestroy()中释放残留的资源
比如,一个音乐播放service可以在onCreate()中创建播放音乐的线程,在onDestory()中停止这个线程
onCreate()和onDestroy()会被所有的service调用,不论service是通过startService()还是bindService()建立


(2)service积极活动的生命时间(active lifetime)是从onStartCommand()或onBind()被调用开始,它们各自处理由startService()或bindService()方法传过来的Intent对象
如果service是被开启的,那么它的活动生命周期和整个生命周期一同结束。
如果service是被绑定的,那么它的活动生命周期是在onUnbind()方法返回后结束。
四、BroadcastReceiver

1、BroadcastReceiver介绍

BroadcastReceiver(广播接收器)是Android系统的四大组件之一,用于监听 / 接收 应用发出的广播消息,并做出响应
应用场景:不同组件之间通信(包括应用内 / 不同应用之间);与 Android 系统在特定情况下的通信(如当电话呼入时、网络可用时);多线程通信
Android 广播分为两个角色:广播发送者、广播接收者
2、实现原理

Android中的广播使用了设计模式中的观察者模式:基于消息的发布/订阅事件模型
模型中有3个角色:

  • 消息订阅者(广播接收者)
  • 消息发布者(广播发布者)
  • 消息中心(AMS,即Activity Manager Service)
广播接收者通过 Binder机制在AMS注册
广播发送者通过 Binder 机制向AMS发送广播
AMS根据广播发送者要求,在已注册列表中,寻找合适的广播接收者(寻找依据:IntentFilter / Permission)
AMS将广播发送到合适的广播接收者相应的消息循环队列中
广播接收者通过消息循环拿到此广播,并回调 onReceive()
3、广播接收器注册

注册的方式分为两种:静态注册、动态注册
(1)静态注册
在AndroidManifest.xml里通过 标签声明
<receiver
    //此广播接收者类是mBroadcastReceiver
    android:name=&#34;.mBroadcastReceiver&#34; >
    //用于接收网络状态改变时发出的广播
    <intent-filter>
        <action android:name=&#34;android.net.conn.CONNECTIVITY_CHANGE&#34; />
    </intent-filter>
</receiver>当此App首次启动时,系统会自动实例化mBroadcastReceiver类,并注册到系统中
静态注册是常驻广播,不受任何组件生命周期的影响
(2)动态注册
在代码中通过调用Context的registerReceiver()方法进行动态注册BroadcastReceiver
@Override
protected void onResume() {  
    super.onResume();  
    //实例化BroadcastReceiver子类 & IntentFilter  
    mBroadcastReceiver mBroadcastReceiver = new mBroadcastReceiver();  
    IntentFilter intentFilter = new IntentFilter();  
    //设置接收广播的类型  
    intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);  
    //调用Context的registerReceiver()方法进行动态注册  
    registerReceiver(mBroadcastReceiver, intentFilter);
}注册广播后,要在相应位置记得销毁广播,即在onPause() 中unregisterReceiver(mBroadcastReceiver)
@Override
protected void onPause() {  
    super.onPause();  
    //销毁在onResume()方法中的广播  
    unregisterReceiver(mBroadcastReceiver);
}当此Activity实例化时,会动态将MyBroadcastReceiver注册到系统中
当此Activity销毁时,动态注册的MyBroadcastReceiver将不再接收到相应的广播
注意:
动态广播最好在Activity的onResume()注册、onPause()注销。
原因:
对于动态广播,有注册就必然得有注销,否则会导致内存泄露
重复注册、重复注销也不允许
动态注册是非常驻广播,灵活,跟随组件的生命周期变化
五、Content Provider

1、Content Provider介绍

Content Provider属于Android应用程序的组件之一,作为应用程序之间唯一的共享数据的途径,Content Provider为存储和读取数据提供了统一的接口。Content Provider主要的功能就是存储并检索数据以及向其他应用程序提供访问数据的接口
Android系统为一些常见的数据类型(如音乐、视频、图像、手机通信录联系人信息等)内置了一系列的Content Provider,这些都位于android.provider包下。持有特定的许可,可以在自己开发的应用程序中访问这些Content Provider
使用Content Provider,应用程序可以实现数据共享
让自己的数据和其他应用程序共享有两种方式:

  • 创建自己的Content Provider(即继承ContentProvider的子类)
  • 将自己的数据添加到已有的Content Provider中去
后者需要保证现有的Content Provider和自己的数据类型相同且具有该Content Provider的写入权限
2、数据模型

Content Provider将其存储的数据以数据表的形式提供给访问者,在数据表中,每一行为一条记录,每一列为具有特定类型和意义的数据。每一条数据记录都包括一个&#34;ID&#34;数值字段,该字段唯一标识一条数据
3、URI

URI(Universal Resource Identifier)统一资源标识符,每一个Content Provider都对外提供一个能够唯一标识自己数据集的公开URI,这个Uri用于表示这个Content Provider提供的数据
Android所提供的Content Provider都存放在android.provider这个包里面
如果一个Content Provider管理多个数据集,其将会为每个数据集分配一个独立的URI。所有的Content Provider的URI都以”content://”开头,其中”content:”是用来标识数据是由Content Provider管理的schema
自定义URI的格式如下:
[scheme:][//Authority][path][?query]
例:content://com.sousuo.people/user/1

  • scheme:主题,Content Provider的URI前缀   content://
  • Authority:授权信息,Content Provider的唯一标识符   com.sousuo.people(包名.类名)
  • path:表名,Content Provider指向数据库中的某个表名   user
  • query:查询表中的某个记录(若无指定,则返回全部记录)  1
4、访问Content Provider中的数据

访问Content Provider中的数据主要通过ContentResolver对象,ContentResolver可以用来对Content Provider中的数据进行查询query()、插入insert()、修改update()和删除delete()等操作,以查询为例,查询一个Content Provider需要掌握如下的信息:

  • 唯一标识Content Provider的URI
  • 需要访问的数据字段名称
  • 该数据字段的数据类型
查询Content Provider的方法有两个:ContentResolver的query()和Activity对象的managedQuery()
二者接收的参数均相同,返回的都是Cursor对象,唯一不同的是使用managedQuery方法可以让Activity来管理Cursor的生命周期
被管理的Cursor会在Activity进入暂停状态的时候调用自己的deactivate()方法自行卸载,而在Activity回到运行状态时会调用自己的requery()方法重新查询生成的Cursor对象。如果一个未被管理的Cursor对象被Activity管理,可以调用Activity的startManagingCursor()方法来实现
Android有一个独特之处就是,数据库只能被它的创建者所使用,其他的应用是不能访问到的,所以如果你想实现不同应用之间的数据共享,就不得不用Content provider了。它提供了一套标准的接口来获取以及操作数据。并且,Android自身也提供了几个现成的content provider:Contacts,Broswer,CallLog,Settings,MediaStore
应用可以通过一个唯一的ContentResolver interface来使用具体的某个content provider
5、提供的函数

query()查询,insert()插入,update()更新,delete()删除,getType()得到数据类型,onCreate()创建时的回调函数
6、实现过程

  定义一个CONTENT_URI常量
  定义一个类,继承Content Provider
  实现query(),delete(),update(),insert(),onCreate(),getType()方法
  在AndroidManifest.xml中声明
7、数据查询

URI有两种形式

  • 一种现实某些数据类型的所有的值(比如,所有的个人联系信息)
  • 还有一种显示某种数据类型的一个特定的记录
content://contacts/people/是第一种形式的URI,它会返回设备上所有的联系人的名字
content://contacts/people/23是第二种形式的URI,只返回ID=23的那行
content://media/images 返回设备上所有图片的列表
Android在android.provider包中提供了一系列的辅助类,它们定义了这些查询字符串,所以不必知道不同数据类型真正的URI值。这些辅助类定义了一个叫CONTENT_URI的字符串
比如android.provider.contacts.People.CONTENT_URI定义了用于在android自带的people content provider中查找联系人的查询字符串
全部回复0 显示全部楼层
暂无回复,精彩从你开始!

快速回帖

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则