Android四大组件总结

news2024/11/15 13:32:23

从事安卓开发也有两年多的时间了,从头开始整理下所学的东西,坚持!!!

一、Activity 活动

  • Activity 用于显示用户界面,用户通过 Activity 交互完成相关操作;   一个 App 允许有多个Activity
  • Activity使用流程 
  • Activiyt启动方式
显示启动:
①最常见的:
startActivity(new Intent(当前Act.this,要启动的Act.class));
②通过Intent的ComponentName:
ComponentName cn = new ComponentName("当前Act的全限定类名","启动Act的全
限定类名") ;
Intent intent = new Intent() ;
intent.setComponent(cn) ;
startActivity(intent) ;
③初始化Intent时指定包名:
Intent intent = new Intent("android.intent.action.MAIN");
intent.setClassName("当前Act的全限定类名","启动Act的全限定类名");
startActivity(intent);
隐世启动:
通过Intent-filter的Action,Category或data来实现
  •  Activity的生命周期

  • 组件间通信
Intent in = new Intent(A, B);
//1.传单个数据
in.putExtra("test","TTIT");
//2.传多个数据
Bundle b = new Bundle();
b.putInt("number", 100);
b.putString("test", "TTIT");
in.putExtras(b);
startActivity(in);

区别:Bundle的内部实际上是使用了HashMap<String, Object>类型的变量来存放putXxx()方法放入的值。简单地说,Bundle就是一个封装好的包,专门用于导入Intent传值的包
存:当我们用putExtras()方法时,所传入的Bundle会被转化为Intent的键值
取:直接使用this.getIntent()就可以得到传来的Intent,然后在这个Intent的基础上调用getExtras()就可以得到Bundle
  • Activity四种启动模式以及任务栈
Activity 管理机制 :
1. 我们的 APP 一般都是由多个 Activity 构成的,而在 Android 中给我们提供了一个 Task( 任务 )
概念, 就是将多个相关的 Activity 收集起来,然后进行 Activity 的跳转与返回 ;
2. 当切换到新的 Activity ,那么该 Activity 会被压入栈中,成为栈顶! 而当用户点击 Back
键,栈顶的 Activity 出栈,紧随其后的 Activity 来到栈顶!
3.Task Activity 的集合,是一个概念,实际使用的 Back Stack 来存储 Activity ,可以有多
Task ,但是 同一时刻只有一个栈在最前面,其他的都在后台
1、standard:标准的启动模式
 Activity默认的启动模式,依次入栈出栈,满足"先进后出"的原则。这种模式下,可以有多个相同的实例,也允许多个相同Activity叠加

2、singleTop:栈顶复用模式
当要启动的目标Activity已经位于栈顶时,不会创建新的实例,会复用栈顶的Activity,并且其onNewIntent()方法会被调用,如果目标Activity不在栈顶,则跟standard一样创建新的实例
应用场景:消息通知,例如qq接收到消息后弹出activity,一次来10条消息,不可能启10个activity吧

3、singleTask:栈内复用模式
在同一个任务栈中,如果要启动的目标Activity已经在栈中,则会复用该Activity,并调用其onNewIntent()方法,并且该Activity上面的Activity会被清除,如果栈中没有,则创建新的实例。
注意: 如果启动模式为singleTask的activity已经在后台一个任务栈中,那么启动后,后台的任务栈将一起被切换到前台
应用场景:这个启动模式通常可以用来退出整个应用,将主activity设为singleTask,然后在要退出的activity中转到主activity,这样就把主activity之上的activity都清除掉,然后重写onNewIntent方法,在方法中加上一句finish(),将最后一个activity也干掉

4、singleInstance:单例模式
指定为singleInstance模式的活动会启用一个新的返回栈来管理这个活动
应用场景:浏览器
  • 启动标志位
1.FLAG_ACTIVITY_NEW_TASK
默认启动标志,该标志控制创建一个新的Activity实例,首先会查找是否存在和被启动的
Activity具有相同的亲和性的任务栈 如果有,则直接把这个栈整体移动到前台,并保持栈中旧
activity的顺序不变,然后被启动的Activity会被压入栈,如果没有,则新建一个栈来存放被
启动的activity
Intent intent = new Intent(A.this, A.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
2.FLAG_ACTIVITY_CLEAR_TOP
如果已经启动了四个Activity:A,B,C和D。在D Activity里,我们要跳到B
Activity,同时希望C finish掉,可以采用下面启动方式,这样启动B Activity,就会把D,
C都finished掉
Intent intent = new Intent(D.this, B.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
3.FLAG_ACTIVITY_SINGLE_TOP
从名字中不难看出该Flag相当于Activity加载模式中的singleTop模式,即原来Activity
栈中有A、B、C、D这4个Activity实例,当在Activity D中再次启动Activity D时,
Activity栈中依然还是A、B、C、D这4个Activity实例。
Intent intent = new Intent(D.this, D.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

二、Service 服务 

程序:为了完成特定任务,用某种语言编写的一组指令集合 ( 一组 静态代码)
进程: 运行中的程序 ,系统调度与资源分配的一个 独立单位,操作系统会 为每个进程
分配一段内存空间!程序的依次动态执行,经历代码的加载,执行, 执行完毕的完整
过程!
线程:比进程更小的执行单元,每个进程可能有多条线程, 线程 需要放在一个 进程中
才能执行,线程由程序 负责管理,而 进程则由系统进行调度!
多线程的理解: 并行 执行多个条指令,将 CPU 时间片按照调度算法分配给各个 线程,
实际上是分时 执行的,只是这个切换的时间很短,用户感觉到 " 同时 "而已!
  • Service 则是 Android 提供一个允许长时间留驻后台的一个组件,最常见的 用法就是做轮询操作!或者想在后台做一些事情,比如后台下载更新!
  • Service 的生命周期 :
    • 生命周期函数解析:
    1 onCreate () :当 Service 第一次被创建后立即回调该方法,该方法在整个生命周期 中只会调用一
    次!
    2 onDestory () :当 Service 被关闭时会回调该方法,该方法只会回调一次!
    3 onStartCommand ( intent , flag , startId ) :早期版本是 onStart ( intent , startId ), 当客
    户端调用 startService ( Intent ) 方法时会回调,可多次调用 StartService 方法, 但不会再创建新 的Service 对象,而是继续复用前面产生的 Service 对象,但会继续回调 onStartCommand( ) 方法!
    IBinder onOnbind(i ntent ) :该方法是 Service 都必须实现的方法,该方法会返回一个 IBinder 对象,app 通过该对象与 Service 组件进行通信!
    4 onUnbind ( intent ) :当该 Service 上绑定的所有客户端都断开时会回调该方法!
  • service启动方式: 下面分别对这三种绑定方式进行说明
1)StartService()启动Service
2)BindService()启动Service
PS:还有一种,就是启动Service后,绑定Service!
  1.  StartService启动Service
首次启动会创建一个 Service 实例 , 依次调用 onCreate() onStartCommand() 方法 , 此时
Service 进入运行状态 , 如果再次调用 StartService 启动 Service, 将不会再创建新的 Service
对象 , 系统会直接复用前面创建的 Service 对象 , 调用它的 onStartCommand() 方法!
但这样的 Service 与它的调用者无必然的联系 , 就是说当调用者结束了自己的生命周期 , 但是只要 不调用stopService, 那么 Service 还是会继续运行的 !
无论启动了多少次 Service, 只需调用一次 StopService 即可停掉 Service

    2.BindService启动Service

当首次使用 bindService 绑定一个 Service , 系统会实例化一个 Service 实例 , 并调用其
onCreate() onBind() 方法 , 然后调用者就可以通过 IBinder Service 进行交互了 , 此后如果
再次使用 bindService 绑定 Service, 系统不会创建新的 Sevice 实例 , 也不会再调用 onBind()
, 只会直接把 IBinder 对象传递给其他后来增加的客户端 !
如果我们解除与服务的绑定 , 只需调用 unbindService(), 此时 onUnbind onDestory 方法将
会被调用 ! 这是一个客户端的情况 , 假如是多个客户端绑定同一个 Service 的话 , 情况如下 当一个客户完成和service 之间的互动后,它调用 unbindService() 方法来解除绑定。当所有的客户端 都和service 解除绑定后,系统会销毁 service 。(除非 service 也被 startService() 方法开
启)
另外 , 和上面那张情况不同 ,bindService 模式下的 Service 是与调用者相互关联的 , 可以理解为
" 一条绳子上的蚂蚱 ", 要死一起死 , bindService , 一旦调用者销毁 , 那么 Service 也立即终
!
通过 BindService 调用 Service 时调用的 Context bindService 的解析
bindService(Intent Service,ServiceConnection conn,int flags)
service : 通过该 intent 指定要启动的 Service
conn :ServiceConnection 对象 , 用户监听访问者与 Service 间的连接情况 , 连接成功回调该对
象中的 onServiceConnected(ComponentName,IBinder) 方法 ; 如果 Service 所在的宿主由
于异常终止或者其他原因终止 , 导致 Service 与访问者间断开 连接时调用
onServiceDisconnected(CompanentName) 方法 , 主动通过 unBindService() 方法断开并
不会调用上述方法 !
flags: 指定绑定时是否自动创建 Service( 如果 Service 还未创建 ), 参数可以是 0( 不自动创
),BIND_AUTO_CREATE( 自动创建 )

   3.StartService启动ServicebindService绑定

如果 Service 已经由某个客户端通过 StartService() 启动 , 接下来由其他客户端 再调用
bindService( )绑定到该 Service 后调用 unbindService() 解除绑定最后在调用
bindService() 绑定到 Service 的话 , 此时所触发的生命周期方法如下 :
onCreate( )->onStartCommand( )->onBind( )->onUnbind( )->onRebind( )
PS: 前提是 :onUnbind() 方法返回 true!!! 说明: 调用了 unbindService
Service 不是应该调用 onDistory() 方法么 ! 其实这是因为这个 Service 是由我们的
StartService 来启动的 , 所以你调用 onUnbind() 方法取消绑定 ,Service 也是不会终止的 !
得出的结论 : 假如我们使用 bindService 来绑定一个启动的 Service, 注意是已经启动的
Service!!! 系统只是将 Service 的内部 IBinder 对象传递给 Activity, 并不会将 Service 的生
命周期 与 Activity 绑定 , 因此调用 unBindService( ) 方法取消绑定时 ,Service 也不会被销
毁!

三、BroadcastReceiver 广播接收器 

  • 为了方便 Android 系统各个应用程序及程序内部进行通信, Android 系统引入了一套广播机制。各 个应用程序可以对感兴趣的广播进行注册,当系统或者其他程序发出这条广播的时候,对发出的广 播进行注册的程序便能够收到这条广播。为此,Android 系统中有一套完整的 API ,允许程序只有的发送和接受广播。
  • 两种基本的广播类型: 标准广播、有序广播
标准广播:
是一种同步执行的广播,在广播发出之后,优先级高的广播接收器可以优先接收到这条广播,
并可以在优先级较低的广播接收器之前截断停止发送这条广播。
发送方式:
Intent intent=new Intent("com.example.dimple.BROADCAST_TEST");
sendOrderBroadcast(intent,null);//第二个参数是与权限相关的字符串。
有序广播:
是一种同步执行的广播,在广播发出之后,优先级高的广播接收器可以优先接收到这条广播,
并可以在优先级较低的广播接收器之前截断停止发送这条广播。
发送方式:
Intent intent=new Intent("com.example.dimple.BROADCAST_TEST");
sendOrderBroadcast(intent,null);//第二个参数是与权限相关的字符串。
  • 注册广播 :
在Android的广播接收机制中,如果需要接收广播,就需要创建广播接收器。而创建广播接收器的
方法就是新建一个类(可以是单独新建类,也可以是内部类(public)) 继承自
BroadcastReceiver
class myBroadcastReceiver extends BroadcastReceiver{
       @Override
       public void onReceive(Context context, Intent intent) {
          //不要在广播里添加过多逻辑或者进行任何耗时操作,因为在广播中是不允许开辟
            线程的, 当onReceiver( )方法运行较长时间(超过10秒)还没有结束的话,那么程序会报错
           (ANR), 广播更多的时候扮演的是一个打开其他组件的角色,比如启动Service,Notification
            提示, Activity等!
      }
}
  • 两种方式注册广播:
1、动态注册的广播接收器可以自由的控制注册和取消,有很大的灵活性。但是只能在程序启动之后才 能收到广播,此外,不知道你注意到了没,广播接收器的注销是在onDestroy() 方法中的。所以广播接收器的生命周期是和当前活动的生命周期一样。
2、静态注册的广播不受程序是否启动的约束,当应用程序关闭之后,还是可以接收到广播。
所谓动态注册是指在代码中注册。步骤如下 :
- 实例化自定义的广播接收器。
- 创建IntentFilter实例。
- 调用IntentFilter实例的addAction()方法添加监听的广播类型。
- 最后调用Context的registerReceiver(BroadcastReceiver,IntentFilter)动
态的注册广播。
PS:这里提醒一点,如果需要接收系统的广播(比如电量变化,网络变化等等),别忘记在
AndroidManifest配置文件中加上权限。
另外,动态注册的广播在活动结束的时候需要取消注册:
@Override
protected void onDestroy() {
     super.onDestroy();
     unregisterReceiver(myBroadcastReceiver);
}
静态注册
<receiver
android:name="com.ttit.core.broadcastreceiver.MyBRReceiver2">
<intent-filter>
<action
android:name="com.example.broadcasttest.MY_BROADCAST" />
</intent-filter>
</receiver>

四、ContentProvider 内容提供者

ContentProvider应用场景: 我们想在自己的应用中访问别的应用,或者说一些ContentProvider暴露给我们的一些数据, 比如 手机联系人,短信等!我们想对这些数据进行读取或者修改,这就需要用ContentProvider了!

我们自己的应用,想把自己的一些数据暴露出来,给其他的应用进行读取或操作,我们也可以用到ContentProvider,另外我们可以选择要暴露的数据,就避免了我们隐私数据的的泄露!

  • 自定义ContentProvider  
我们自己的应用,想把自己的一些数据暴露出来,给其他的应用进行读取或操作,我们也可以用 到 ContentProvider,另外我们可以选择要暴露的数据,就避免了我们隐私数据的的泄露!

  • ContentObserver:内容观察者,目的是观察特定Uri引起的数据库的变化,方便监听插入数据库中数据的变化
创建内容观察者 ContentObserver
2、注册监听 registerContentObserver
3、刷新数据库改变  onChange (内容观察者即可收到消息)
4、注销监听 unregisterContentObserver  (页面销毁或程序关闭的时候)
1、ContentProvider——内容提供者
对外提供数据,通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider 对你应用中的数据进行添删改查。

2、ContentResolver——内容解析者
 按照一定规则访问内容提供者的数据(其实就是调用内容提供者自定义的接口来操作它的数据)。

3、ContentObserver——内容监听器
监听(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理,它类似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它。

ContentResolver.notifyChange(uri)  发出消息。
ContentResolver.registerContentObserver() 监听消息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1164133.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

贝锐向日葵亮相阿里云“云栖大会”:独创专利算法赋能全新云桌面

2023年10月31日-11月2日&#xff0c;一年一度的云栖大会如期举办&#xff0c;国产远程连接服务创领者贝锐受邀参与。活动现场&#xff0c;贝锐CTO张小峰进行了分享&#xff0c;宣布贝锐旗下国民级远程控制品牌“贝锐向日葵”与无影展开合作&#xff0c;同时全新的“云桌面”将于…

1360. 日期之间隔几天

1360. 日期之间隔几天 Java代码&#xff1a; 【DateFormat】DateFormat用于实现日期的格式化 import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; // 好像已过时class Solution {public int daysBet…

RHCE---shell脚本编程之awk

文章目录 目录 文章目录 前言 一.awk概念 二.工作流程 三.awk执行方式 四.awk 语法结构及案例 纯命令执行脚本 awk命令调用脚本执行 直接awk纯脚本执行 五.记录和域 概念&#xff1a; 六.awk的变量 总结 前言 前文已详细了介绍了文本三剑客的其中两种grep 和 sed 命…

C++查看Class类结构

cl指令 cl test.cpp /d1reportSingleClassLayout 类名 注意。上面指令是d1,1是数字1 &#xff0c; 不是字母l;

深度解析concrt140.dll丢失的5个解决方法,快速搞定dll问题

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“concrt140.dll丢失”。这个问题通常会导致某些应用程序无法正常运行&#xff0c;给用户带来困扰。本文将介绍一种有效的解决方法&#xff0c;帮助用户解决concrt140.dll丢失的问题。 一、原…

时序分解 | Matlab实现NGO-VMD北方苍鹰算法优化变分模态分解时间序列信号分解

时序分解 | Matlab实现NGO-VMD北方苍鹰算法优化变分模态分解时间序列信号分解 目录 时序分解 | Matlab实现NGO-VMD北方苍鹰算法优化变分模态分解时间序列信号分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 北方苍鹰算法NGO优化VMD&#xff0c;对其分解层数&#xff…

【Algorithm】最容易理解的蒙特卡洛树搜索(Monte Carlo Tree Search,MCTS)算法

看了不少解读和笔记&#xff0c;本文把最容易理解的解读做个总结。 1. 蒙特卡洛方法 蒙特卡洛方法(Monte Carlo method)&#xff0c;是一种“统计模拟方法”。20世纪40年代&#xff0c;为建造核武器&#xff0c;冯.诺伊曼 等人发明了该算法。因赌城蒙特卡洛而得名&#xff0c…

【HSPICE仿真】输入网表文件(6)用户自定义分析输出(.measure)

.measure语句的基本用法 1. 语句顺序2. 测量参数类型3. Rise, Fall, Delay, and Power Measurements4. FIND 和 WHEN 函数5. Equation Evaluation/Arithmetic Expression6. AVG, EM_AVG, INTEG, MIN, MAX, PP, and RMS基本语法示例 7. 输出文件格式MEASFORMMEASOUTMEASFILEMEAS…

程序员想要网上接单却看花了眼?那这几个平台你可得收藏好了!

现在经济压力这么大&#xff0c;但是生活成本还在上升&#xff0c;相信大家都知道“四脚吞金兽”的威力了吧&#xff01;话虽如此&#xff0c;但是生活总得继续&#xff0c;为了家庭的和谐幸福&#xff0c;为了孩子的未来&#xff0c;不少人选择多干几份工作&#xff0c;赚点外…

多态与虚函数、虚函数表、对象的内存模型的思考

我在这就不详细说多态、虚函数是什么了&#xff0c;简单理解为&#xff1a; 1.基类定义虚函数 2.派生类重定义/重写&#xff08;override&#xff09;基类的虚函数 3.基类指针&#xff08;引用&#xff09;指向&#xff08;绑定&#xff09;到派生类对象 4.基类指针&#xff08…

大数据Doris(十五):Doris表的字段类型

文章目录 Doris表的字段类型 一、TINYINT数据类型 二、SMALLINT数据类型 三、INT数据类型

以太网【FPGA】

1物理&#xff1a; 2接线&#xff1a; 信号名 信号类型 对应引脚 备注 sys_clk Input B5 系统晶振输入时钟&#xff0c;频率 50MHz sys_rst_n Input E8 系统复位信号&#xff0c;低有效 eth_rxc Input E17 PHY 输入时钟&#xff0c;频率 125MHz eth_rx_ctl Inpu…

傅里叶分析和小波分析

从傅里叶变换到小波变换&#xff0c;并不是一个完全抽象的东西&#xff0c;可以讲得很形象。小波变换有着明确的物理意义&#xff0c;如果我们从它的提出时所面对的问题看起&#xff0c;可以整理出非常清晰的思路。 下面我就按照傅里叶-->短时傅里叶变换-->小波变换的顺…

损失函数(Loss Function)一文详解-聚类问题常见损失函数Python代码实现+计算原理解析

损失函数(Loss Function)一文详解-聚类问题常见损失函数Python代码实现计算原理解析 前言 损失函数无疑是机器学习和深度学习效果验证的核心检验功能&#xff0c;用于评估模型预测值与实际值之间的差异。我们学习机器学习和深度学习或多或少都接触到了损失函数&#xff0c;但…

SuperMap iServer 11i(2023)安全性提升汇总

作者&#xff1a;lisong 目录 账户信息合规度校验规则扩展功能图片验证码登录功能Web服务提供者密码加密数据库密码加密漏洞修复 SuperMap iServer 11i&#xff08;2023&#xff09;产品安全性相关的提升众多&#xff0c;涵盖账户安全、服务安全以及漏洞修复等方面&#xff0c;…

2023杭州·云栖大会:我在云栖看数智中国

目录 模型即服务&#xff08;MaaS&#xff0c;Model as a Service&#xff09;全球首个李白数字展我在云栖看数智中国 云栖之眼、视频云3D渲染、数字人…… 10月31日到11月2日&#xff0c;2023云栖大会在杭州市西湖区云栖小镇火热进行&#xff0c;本次的主题为“ 计算&#xff…

YOLO目标检测——红外多目标检测数据集【含对应voc、coco和yolo三种格式标签】

实际项目应用&#xff1a;自动驾驶、安防监控等数据集说明&#xff1a;红外多目标检测数据集&#xff0c;真实场景的高质量图片数据&#xff0c;数据场景丰富&#xff0c;含有行人、汽车、自行车、摩托、消防栓、指示牌、狗等图片标签说明&#xff1a;使用lableimg标注软件标注…

题解数量上三百了

题解数量上三百了 持之以恒&#xff0c;不断进步。

近独立粒子的最概然分布

近独立粒子&#xff1a;粒子之间相互作用微弱基本粒子中&#xff0c;自旋量子数为半整数的有 电子 、 质子 、中子、中微子自旋量子数为整数的有 光子、pi介子 经典力学描述系统的微观运动状态 经典力学中&#xff0c;全同粒子可以分辨量子力学&#xff0c;全同粒子不可以分辨微…

JMeter接口测试性能测试

目前最新版本发展到5.0版本&#xff0c;需要Java7以上版本环境&#xff0c;下载解压目录后&#xff0c;进入\apache-jmeter-5.0\bin\&#xff0c;双击ApacheJMeter.jar文件启动JMemter。 1、创建测试任务 添加线程组&#xff0c;右击测试计划&#xff0c;在快捷菜单单击添加-…