Activity和Service都继承了ContextWrapper,所以可以直接调用。在实际应用中,我们在Activity或Service中注册了一个BroadcastReceiver,当这个Activity或Service被销毁时如果没有解除注册,系统会报一个异常,提示我们是否忘记解除注册了。所以,需要在特定的地方执行解除注册操作:生命周期的onDestroy()。
有部分广播接受者,涉及到用户的敏感内容,需要在权限文件中声明。如开机完成的广播,用户电量变化的广播,用户网络状态发生改变的广播 2.3.3 生命周期
1. 广播接收者的生命周期是非常短暂的,在接收到广播的时候创建,
onReceive()方法结束之后销毁
2. 广播接收者中不要做一些耗时的工作,否则会弹出Application No Response
错误对话框
3. 最好也不要在广播接收者中创建子线程做耗时的工作,因为广播接收者被销
毁后进程就成为了空进程,很容易被系统杀掉
4. 耗时的较长的工作最好放在服务中完成
3 Service
3.1 概念
服务是看不到界面的,,就是一个没有界面的Activity, 并且长期在后台运行的一个组件.。
3.2 为什么用服务?
进程优先级, 回收时是从5~1, 从低到高 Foreground process 前台进程 Visible process 可视进程 Service process 服务进程 Background process 后台进程 Empty process 空进程
回收的优先级: 先回收空进程, 一个一个回收的, 当内存够用时, 不再回收空进程. 如果空进程回收完毕后, 内存还是不够用时, 继续向上一个一个的回收后台进程. 依次类推.
当系统内存不够用时, 需要回收服务进程时, 当系统内存又够用时, 会重新启动服务. 当用户去手动的把服务关闭时, 服务不会再重启了
3.3 作用
由于ANR对Activity和BroadcastReceiver响应时间的限制(Activity对事件响应不超过5秒,BroadcastReceiver执行不超过10秒),使得在其中都不适合执行较耗时操作,这样像网络、数据库、复杂计算这类耗时操作的执行就需要一个组件来承担。Service作为Android四大组件之一,其功能之一就是耗时操作的执行,主要功能如下:
a. 执行需要长时间运行的操作,这个操作不与用户进行交互,如网络下载、大文件I/O、复杂计算、监听手机状态。
b. 应用内或应用间数据通信,Android每个应用程序都在自己的dalvik虚拟机中运行,一个应用是不允许访问其他应用的内存信息的,为此Android引入了Content Provider在不同应用间共享数据,BroadcastReceiver广播信息给不同应用程序,但Content Provider更多用于数据的共享,BroadcastReceiver广播的信息会被所有应用接收较耗费系统资源,对于两个应用间动态的进行交互还需要通过Service来完成。
3.4 启动方式
3.4.1 直接启动
Activity开启完服务后就不管服务了. Activity和服务没有关系. startService开启的服务, 只有stopService可以关闭 3.4.2 绑定启动
绑定服务, 生命周期方法会执行: onUnbind -> onDestory 服务销毁了. 在activity中调用service中的方法.
步骤:
调用bindService方法绑定服务
1. 在Activity中定义一个连接桥的内部类, 会在bindService方法传递给
service.
2. 在service服务中onBind方法中返回一个IBinder接口对象.
3. 在service类中定义一个IBinder的内部实现类, 在onBind方法返回. 4. 当onBinder方法返回完对象后, activity中连接桥里的
onServiceConnected会被调用, 其中形参IBinder service就是
service类中onBind返回的对象.
5. activity得到了service中的内部类对象, 点击按钮是调用内部类中的
forwardBuyTicket方法, 此方法会转调服务中buyTicket方法.
3.5 生命周期
Service的生命周期 (适用于2.1及以上) 1. 被startService的
无论是否有任何活动绑定到该Service,都在后台运行。
onCreate(若需要) -> onStart(int id, Bundle args). 多次startService,则onStart调用多次,但不会创建多个Service实例,只需要一次stop。该Service一直后台运行,直到stopService或者自己的stopSelf()或者资源不足由平台结束。
2. 被bindService的
调用bindService绑定,连接建立服务一直运行。未被startService只是BindService,则onCreate()执行,onStart(int,Bund,le)不被调用;这种情况下绑定被解除,平台就可以清除该Service(连接销毁后,会导致解除,解除后就会销毁)。
3. 被启动又被绑定
类似startService的生命周期,onCreate onStart都会调用。 4. 停止服务时
stopService时显式onDestroy()。或不再有绑定(没有启动时)时隐式调用。有bind情况下stopService()不起作用。
4 ContentProvider
4.1 ContentProvider
数据库在Android当中是私有的,当然这些数据包括文件数据和数据库数据以及一些其他类型的数据。
不能将数据库设为WORLD_READABLE,每个数据库都只能创建它的包访问, 这意味着只有由创建数据库的进程可访问它。如果需要在进程间传递数据, 则可以使用AIDL/Binder或创建一个ContentProvider,但是不能跨越进程/包边界直接来使用数据库。
一个Content Provider类实现了一组标准的方法接口,从而能够让其他的应用保存或读取此Content Provider的各种数据类型。
也就是说,一个程序可以通过实现一个Content Provider的抽象接口将自己的数据暴露出去。
外界根本看不到,也不用看到这个应用暴露的数据在应用当中是如何存储的,或者是用数据库存储还是用文件存储,还是通过网上获得,这些一切都不重要,
重要的是外界可以通过这一套标准及统一的接口和程序里的数据打交道,可以读取程序的数据,也可以删除程序的数据,
当然,中间也会涉及一些权限的问题。下边列举一些较常见的接口,这些接口如下所示。
· query(Uri uri, String[] projection, String selection, String[]
selectionArgs,String sortOrder):通过Uri进行查询,返回一个Cursor。
· insert(Uri url, ContentValues values):将一组数据插入到Uri 指定的地方。
· update(Uri uri, ContentValues values, String where, String[] selectionArgs):更新Uri指定位置的数据。
· delete(Uri url, String where, String[] selectionArgs):删除指定Uri并且符合一定条件的数据。
4.2 ContentResolver
外界的程序通过ContentResolver接口可以访问ContentProvider提供的数据,在Activity当中通过getContentResolver()可以得到当前应用的 ContentResolver实例。
ContentResolver提供的接口和ContentProvider中需要实现的接口对应,主要有以下几个。
? query(Uri uri, String[] projection, String selection, String[]
selectionArgs,String sortOrder):通过Uri进行查询,返回一个Cursor。
? insert(Uri url, ContentValues values):将一组数据插入到Uri 指
定的地方。
? update(Uri uri, ContentValues values, String where, String[]
selectionArgs):更新Uri指定位置的数据。
? delete(Uri url, String where, String[] selectionArgs):删除指
定Uri并且符合一定条件的数据。
4.3 ContentObserver
在注册,翻译成中文就是内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理。ContentObserver一般和系统或第三方程序提供的Provider一起使用,这些Provider一般情况下会有一个Uri,然后ContentObserver就去监听这些Uri数据的变化,然后做出相应的处理。
4.4 ContentProvider和ContentResolver中用到的Uri
在ContentProvider和 ContentResolver当中用到了Uri的形式通常有两种,一种是指定全部数据,另一种是指定某个ID的数据。
我们看下面的例子。 · content://contacts/people/ 这个Uri指定的就是全部的联系人数据。 · content://contacts/people/1 这个Uri指定的是ID为1的联系人的数据。
在上边两个类中用到的Uri一般由3部分组成。
· 第一部分是方案:\这部分永远不变