Android四大组件

摘抄自https://www.jianshu.com/p/51aaa65d5d25,只选取部分觉得需要记录一下的内容,用于查阅

Activity

生命周期图:

在这里插入图片描述

onPause()执行相关

表示activity正在停止,此时可以做一些存储数据,停止动画等工作,注意不能太耗时,因为这会影响到新activity的显示,onPause必须先执行完,新的activity的onResume才会执行
当activity中弹出dialog对话框的时候,activity不会回调onPause。
然而当activity启动dialog风格的activity的时候,此activity会回调onPause函数。

Activity生命周期异常情况

情况1:资源相关的系统配置发生改变导致activity被杀死并重新创建
比如说当前activity处于竖屏状态,如果突然旋转屏幕,由于系统配置发生了改变,在默认情况下,activity就会被销毁并且重新创建,当然我们也可以组织系统重新创建我们的activity。
系统配置发生改变以后,activity会销毁,其onPause,onStop,onDestory均会被调用,由于activity是在异常情况下终止的,系统会调用onSaveInstance来保存当前activity状态,这个方法的调用时机是在onStop之前。与onPause没有既定的时序关系,当activity重新创建后,系统会调用onRestoreInstanceState,并且把activity销毁时onSaveInstanceState方法保存的Bundle对象作为参数同时传递给onRestoreInstanceState和onCreate方法。onRestoreInstanceState()在onStart()方法后回调。
在这里插入图片描述在这里插入图片描述

同时,在onSaveInstanceState和onRestoreInstanceState方法中,系统自动为我们做了一些恢复工作,如:文本框(EditeText)中用户输入的数据,ListView滚动的位置等,这些view相关的状态系统都能够默认为我们恢复。可以查看view源码,和activity一样,每个view都有onSaveInstanceState方法和onRestoreInstanceState方法。

情况2:资源内存不足导致低优先级的activity被杀死
这里的情况和前面的情况1数据存储和恢复是完全一致的,activity按照优先级从高到低可以分为如下三种:
(1)前台activity—正在和用户交互的activity,优先级最高
(2)可见但非前台activity—比如activity中弹出了一个对话框,导致activity可见但是位于后台无法和用户直接交互。
(3)后台activity—已经被暂停的activity,比如执行了onStop,优先级最低。
重新创建activity:activity指定configChange属性来不让系统重新创建activity。
android : configChanges = “orientation”

Activity与Fragment生命周期关系

创建
在这里插入图片描述
销毁
在这里插入图片描述

Activity与menu创建先后顺序

在activity创建完回调onResume后创建menu,回调onCreateOptionsMenu

Activity的启动模式

tandard模式:在这种模式下,activity默认会进入启动它的activity所属的任务栈中。 注意:在非activity类型的context(如ApplicationContext)并没有所谓的任务栈,所以不能通过ApplicationContext去启动standard模式的activity
singleTop模式:栈顶复用模式。如果新activity位于任务栈的栈顶的时候,activity不会被重新创建,同时它的onNewIntent方法会被回调。 注意:这个activity的onCreate,onStart,onResume不会被回调,因为他们并没有发生改变。
singleTask模式:栈内复用模式。只要activity在一个栈中存在,那么多次启动此activity不会被重新创建单例,系统会回调onNewIntent
singleInstance模式:单实例模式。默认情况下,所有activity所需的任务栈的名字为应用的包名,可以通过给activity指定TaskAffinity属性来指定任务栈,这个属性值不能和包名相同,否则就没有意义 。

Service

基本说明

调用者和service在同一个进程里,所以运行在主进程的main线程中。所以不能进行耗时操作,可以采用在service里面创建一个Thread来执行任务。任何 Activity 都可以控制同一 Service,而系统也只会创建一个对应 Service 的实例。

两种启动方式

第一种:start
不在使用时,调用stopService(Intent)方法停止服务
使用start方式启动的生命周期:
onCreate() – > onStartCommand() – > onDestory()
注意:如果服务已经开启,不会重复回调onCreate()方法,如果再次调用context.startService()方法,service而是会调用onStart()或者onStartCommand()方法。
特点:
一旦服务开启就跟调用者(开启者)没有任何关系了。开启者退出了,开启者挂了,服务还在后台长期的运行,开启者不能调用服务里面的方法。
第二种:bind
不再使用时,调用unbindService(ServiceConnection)方法停止该服务
使用这种bind方式启动的service的生命周期如下:
onCreate() – > onBind() --> onUnbind() – > onDestory()
注意:绑定服务不会调用onStart()或者onStartCommand()方法
特点:bind的方式开启服务,绑定服务,调用者挂了,服务也会跟着挂掉。绑定者可以调用服务里面的方法。

IntentService

IntentService是Service的子类,比普通的Service增加了额外的功能。先看Service本身存在两个问题:
Service不会专门启动一条单独的进程,Service与它所在应用位于同一个进程中;
Service也不是专门一条新线程,因此不应该在Service中直接处理耗时的任务;
IntentService特征:
会创建独立的worker线程来处理所有的Intent请求;
创建独立的worker线程来处理onHandleIntent()方法实现的代码,无需处理多线程问题;
所有请求处理完成后,IntentService会自动停止,无需调用stopSelf() 方法停止Service;
为Service的onBind()提供默认实现,返回null;
为Service的onStartCommand提供默认实现,将请求Intent添加到队列中;
Github: ServiceDemo

BroadcastReceiver

普通广播是完全异步的,可以在同一时刻(逻辑上)被所有接收者接收到,消息传递的效率比较高,但缺点是:接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播;然而有序广播是按照接收者声明的优先级别(声明在intent-filter元素的android:priority属性中,数越大优先级别越高,取值范围:-1000到1000。也可以调用IntentFilter对象的setPriority()进行设置),被接收者依次接收广播。
注意 :BroadcastReceiver生命周期很短
不应该在BroadcastReceiver中开启一个新的线程,因为BroadcastReceiver生命周期很短,在执行完onReceiver以后就结束,如果开启一个新的线程,可能出现BroadcastRecevier退出以后线程还在,而如果BroadcastReceiver所在的进程结束了,该线程就会被标记为一个空线程,根据Android的内存管理策略,在系统内存紧张的时候,会按照优先级,结束优先级低的线程,而空线程无异是优先级最低的,这样就可能导致BroadcastReceiver启动的子线程不能执行完成。
广播还可以通过动态注册,一定要加上这个权限
android:name=“android.permission.PROCESS_OUTGOING_CALLS”

ContentProvider

它主要的作用就是将程序的内部的数据和外部进行共享,为数据提供外部访问接口,被访问的数据主要以数据库的形式存在,而且还可以选择共享哪一部分的数据。ContentProvider是android中一种跨程序共享数据的重要组件。 也可以使用系统的ContentProvider。系统的ContentProvider有很多,如通话记录,短信,通讯录等等,都需要和第三方的app进行共享数据。既然是使用系统的,那么ContentProvider的具体实现就不需要我们担心了。