1.Activity系列
1.1 Activity的生命周期
activity的生命周期方法为onCreate()、onStart()、onResume()、onPause()、onStop()、onDestroy()、后面再加一个再次启动时的onRestart();
- 打开A Activity,分别执行onCreate()、onStart()、onResume()
- 从A Activity打开B Activity,分别执行A onPause(), B onCreate(),B onStart(),B onResume(),A onStop()
- 关闭B Activity,分别执行B onPause(),A onRestart(),A start(),A resume(),B onStop(), B on Destroy()
- 将A Activity由竖屏切换为横屏,如果清单文件中没有设置android:configChanges属性,则先销毁再创建,即 onPause(),onStop(),onDestroy(),onCreate(),onStart(),onResume(),设置了orientation|screenSize(一定要同时出现)属性值之后,不再走生命周期方法,直接调用onConfigrationChanged()方法。
- Activity切换中onPause()和onStop()方法比较特殊,在onPause()方法中中不要加入太多耗时的操作,会影响用户体验,
1.2 Activity的启动模式
task:翻译过来就是‘任务’,是一组相互有关联的activity的集合,可以理解为activity是在task里面活动的,task存在于一个叫back stack的数据结构中的,他是以栈的方式去管理activity的,因此也被称为任务栈。
taskAffinity:taskAffinity可以翻译为activity相关或关联的任务,这个参数标记了这个activity所需要任务栈的名字,默认情况下,activity相关任务栈的名字是应用程序的包名。taskAffinity与singleTask模属性启动模式或者allowTaskReparenting属性配对使用。
4种启动模式:
standard:标准模式,在A Activity中启动B Activity,不管A Activity所在的栈中是否含有B Activity的实例,都会new 一个B Activity的实例放在A所在栈的栈顶。非Activity的Context启动standard模式(如ApplicationContext)会报错。
singleTop:栈顶复用模式,在A Activity中启动B Activity,查看A所在的任务栈栈顶是否是B Activity的实例,如果是,则不需要new B Activity的实例而是直接引用栈顶的实例,并且回调onNewIntent()方法,通过该方法的参数可以取得请求的信息。如果不是,会再new 一个B Activity的实例,而会使用这个栈顶的B Activity。
singleTask:栈内复用模式,启动一个Activity,先从系统中查找与activity的taskAffinity属性相匹配的任务栈是否存在,如果不存在,创建栈,然后new Activity的实例放入栈中,如果存在,则在栈中寻找该实例,如果该实例存在,销毁栈中该activity 上面的所有activity,最终让该activity位于栈顶。如果实例不存在,则直接创建一个实例并压入栈顶。
singleInstance:单实例模式,是SingleTask的加强版,除了singleTask的功能外,此模式的Activity必须单独地位于一个任务栈,不与其他Activity位于同一栈内。
1.3 onCreate与onSaveInstanceState与onRestoreInstanceState
1)、onCreate(Bundle savedInstanceState) 方法
Activity 创建时回调 : 该方法会自动传入一个 Bundle 对象, 该 Bundle 对象就是上次被系统销毁时在 onSaveInstanceState 或者 onRestoreInstanceState 中保存的数据
-- 注意 : 只有是系统自动回收的时候才会保存 Bundle 对象数据;
-- Bundle 对象来源 : onCreate() 方法中的 Bundle 对象参数, 是在 onSaveInstance() 或者 onRestoreInstanceState() 方法中保存的 Bundle 对象;
2)、 onSaveInstanceState(Bundle outState) 方法
onSaveInstanceState函数是Activity的生命周期函数
outState 参数作用 :
数据保存 : Activity 生命周期结束的时候, 需要保存 Activity 状态的时候, 会将要保存的数据使用键值对的形式 保存在 Bundle 对象中;
恢复数据 : 在 Activity 的 onCreate()方法 创建 Activity 的时候会传入一个 Bundle 对象, 这个 Bundle 对象就是这个 outState 参数;
调用时机 : Activity 容易被销毁的时候调用, 注意是容易被销毁, 也可能没有销毁就调用了;
按下Home键 : Activity 进入了后台, 此时会调用该方法;
按下电源键 : 屏幕关闭, Activity 进入后台;
启动其它 Activity : Activity 被压入了任务栈的栈底;
横竖屏切换 : 会销毁当前 Activity 并重新创建;
onSaveInstanceState方法调用注意事项 :
用户主动销毁不会调用 : 当用户点击回退键 或者 调用了 finish() 方法, 不会调用该方法;
调用时机不固定 : 该方法一定是在 onStop() 方法之前调用, 但是不确定是在 onPause() 方法之前 还是 之后调用;
布局中组件状态存储 : 每个组件都 实现了 onSaveInstance() 方法, 在调用函数的时候, 会自动保存组件的状态, 注意, 只有有 id 的组件才会保存;
关于默认的 super.onSaveInstanceState(outState) : 该默认的方法是实现 组件状态保存的;
(3) onRestoreInstanceState(Bundle savedInstanceState) 方法
方法回调时机 : 在 Activity 被系统销毁之后 恢复 Activity 时被调用, 只有销毁了之后重建的时候才调用, 如果内存充足, 系统没有销毁这个 Activity, 就不需要调用;
-- Bundle 对象传递 : 该方法保存的 Bundle 对象在 Activity 恢复的时候也会通过参数传递到 onCreate() 方法中;
——————————————————————————————————————————————————————
2.Service系列
2.1 Service的生命周期
Service的生命周期方法有以下几种:
4个手动调用的方法:
- startService()
- stopService()
- bindService()
- unbindService();
5个内部调用的方法:
- onCreate() //创建服务
- onStartCommand() //开启服务
- onDestroy() //停止服务
- onBind() //绑定服务
- onUnbind() //解除绑定
- 手动调用startService()方法,内部执行onCreate()、onStartCommand()方法,如果一个Service被startService()了多次,但是只会onCreate()一次。
- 手动调用stopService()方法,内部执行onDestroy()方法,但是如果Service已经绑定,则无法停止服务除非已经解绑
- 手动调用bindService()方法,内部执行onCreate(),onBind()方法
- 手动调用unvindService()方法,内部执行onUnbind(),onDestroy()方法
- startService()和stopService()只能开启和停止Service,但是不能操作Service,所以服务还在。而bindService()和unbindService()可以操作Service,调用者退出后,Service会随着销毁。
2.2 Service的缺点
默认情况下, 是在main Thread中进行的,所以一般进行复杂的操作需要开启新的线程。一般在onStartCommand()中可以执行一些轻量的网络操作。
- Service不会专门启动一条单独的进程,它与所在的应用程序处于同一进程。
- Service也不是专门一条新的线程,因此不应该在Service中直接进行耗时的操作(可以开启一条新的线程)
2.3 IntentService————(因Service的缺点而产生)
特征:
-
- 会创建独立的Worker线程来处理所有的Intent请求。
- 会创建独立的Worker线程来处理onHandlerIntent()实现的代码,不需要处理多线程问题。
- 所有的请求完成后,IntentService自动停止,不需要调用stopSelf()来停止Service;
- 为Service的onBind()提供默认实现,返回null;
- 为Service的onStartCommand()提供默认实现,将Intent请求添加到队列中。
让Service类继承IntentService,重写onStartCommand()与onHandlerIntent()方法。
启动Service的方式有两种,根据action获取Service时应该设置好包名;
————————————————————————————————————————————————————————
3. BroadCastReceiver
3.1 Android引入广播机制的意义
为了方便四大组件之间数据与信息的交互。
程序间互通消息(如监听系统来电)
效率上(如UDP的广播协议在局域网上的方便性)
设计模式上(反转控制的一种应用,类似于监听者模式)
3.2 广播注册
首先写一个类继承BroadCastReceiver;
静态注册
<receiver>
<intent-filter>
<action name="android.provider.Telephony.SMS_RECEIVED"/>
</intent/filter>
</receiver>
动态注册
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
MyBroadCastReceiver myreceiver = new MyBroadCastReceiver();
registerReceiver(myreciver.filter);
两种方式的比较:
- 静态注册:常驻型广播,程序关闭也能收到短信,程序会被系统自动调用
- 动态注册:非常驻型广播,也就是说广播跟着程序的生命周期。
发送广播的两种方式:
- 同步广播:Context.sendBrodcast()
- 有序广播:Context.sendOrderedBrodcast()
3.3 广播接收者的生命周期
- 广播接收者的生命周期非常的短,当调用onRecieve()方法后,广播就会销毁
- 在广播接收中不能进行耗时的操作
- 在广播接收者不能创建子线程。广播接收者完成操作后,所在的进程会变为空进程,很容易被系统回收。
————————————————————————————————————————————————————————
4.ContentProvider
4.1ContentProvider的作用
ContentProvider用于提供第三方应用数据的访问方案,可以派生ContentProvider类,对外提供接口。
4.2ContentProvider、ContentResolve、ContentObserver之间的关系
ContentProvider:内容提供者,对外提供数据内容,contentprovider.notifyChanges(uri)更新提供内容。
ContentResolver:内容解析者,解析ContentProvider提供的内容。
ContentObserver:内容监听者,监听数据的变化,contentObserver.registerContentObserver()
————————————————————————————————————————————————
5.四大组件之间的交互
activity之间的交互:使用Intent传递数据,startActivity(Intent intent)
activity与service之间的交互:使用Intent传递数据,startService(Intent intent)
activity与BroadcastReceiver之间的交互:使用Intent传递数据,sendBroadcast(Intent intent)