Android四大组件(Service篇)
来源:互联网 发布:怎样删除精选淘宝 编辑:程序博客网 时间:2024/06/16 14:51
什么是Service
Service是运行于Android后台的程序操作,无用户交互界面。
创建一个服务,只需要继承android.app.Service类即可。而其中必须实现的方法只有一个
@Overridepublic IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service.}
若不实现该方法,将会抛出异常。该方法将返回一个IBinder对象。IBinder是一个Interface,因此,我们需要在Service中定义一个Binder类(该类实现了IBinder接口),并在onBinder中返回。而绑定Service的Activity可通过强行转换,获取自定义的Binder类。
当然,如果不想Service被绑定,可以不定义,返回null即可。
注:作为Android的四大组件,Service也需要在Manifest中进行声明。如果使用Android Studio的创建向导,声明将被自动添加。
<application android:allowBackup="true" android:label="@string/app_name" android:supportsRtl="true"> <service android:name=".myService" android:enabled="true" android:exported="true"></service> </application>
注:enabled表示是否启用这个Service,exported表示该服务能否被其他程序访问。
Service中常用的监听方法
(1)public void onCreate()
Service是一个单例。当Service第一次被创建时,该方法被调用。
(2)public int onStartCommand(Intent intent, int flags, int startId)
当Service被启动时,该方法被调用。每个Service都可以被启动多次,因此,该方法可以被调用多次。
(3)public void onDestroy()
当Service被销毁时,该方法被调用。
(4)public IBinder onBind(Intent intent)
当Service被绑定时,该方法被调用。
(5)public boolean onUnbind(Intent intent)
当Service被解绑时,该方法被调用。
如何触发Service
(1)Start/Stop方式
启动Service
intent=new Intent(this, myService.class);startService(intent);
若此时Service未创建,则将依次触发
myServiceonCreateonStartCommand
否则,仅触发
onStartCommand
停止服务
intent=new Intent(this, myService.class);stopService(intent);
停止服务将会触发
onDestroy
onDestroy跟onCreate一样,仅被触发一次。
(2)Bind/Unbind方式
若Service提供多种服务,比如func1,func2,我们该如何调用呢?
此时startService/stopService方式便不能满足要求了。因此,我们通过绑定的方式,获取服务代理,该代理即为Binder。
(a)在自定义的Binder类当中实现func1,func2。
public class myBinder extends Binder { private final String TAG=getClass().getName(); public void fun1(){ Log.i(TAG, "fun1: "); } public void fun2(){ Log.i(TAG, "fun2: "); }}
(b)当Activity绑定Service时,将自定义的Binder实例提通过onBind接口供给Activity。
public class myService extends Service { private final String TAG=getClass().getName(); private myBinder m_Binder; public myService() { Log.i(TAG, "myService: Thread id = "+Thread.currentThread().getId()); m_Binder=new CalculateBinder(); } @Override public void onDestroy() { m_Binder=null; super.onDestroy(); } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. return m_Binder; }}
(c)ServiceConnection接口
绑定Service是异步操作,因此,需要回掉方法来通知Activity,是否已经与Service建立连接。
ServiceConnection m_servic eConnection=new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { m_Binder=(CalculateBinder) iBinder; } @Override public void onServiceDisconnected(ComponentName componentName) { m_Binder=null; }};
若连接建立成功,onServiceConnected方法将会被触发,iBinder即为onBind方法返回的Service代理。
这里需要对onServiceDisconnected进行特殊说明。onServiceDisconnected方法仅在Service异常丢失(并非onDestroy)时触发。系统资源不足时,会对资源进行回收,而Service的优先级别并不高,因此可能触发Service的丢失情况。
(d)绑定Service
intent=new Intent(this, myService.class);bindService(intent,m_serviceConnection, Context.BIND_AUTO_CREATE);
bindService将触发以下Service生命周期监听方法
onCreateonBind
(e)解绑Service
unbindService(m_serviceConnection);
若在bindService前,Service未被启动,或未被多个Activity绑定,则unbindService将触发以下Service生命周期监听方法
onUnbindonDestroy
若bindService前,Service已被启动,或被多个Activity绑定,则unbindService将仅触发onUnbind方法。
需要注意的是,即使startService()仅被调用了一次,stopService()也可被多次调用。但对于bindService和unbindService就不同了。bindService可被多次调用。unbindService仅能被调用一次。若多次调用,将引发异常。
java.lang.IllegalArgumentException: Service not registered: com.breakloop.servicedemo.MainActivity$1@2ebc9d4
Service的问题
问题来了~
(1)Service能否关闭自己?
当然可以!在需要的位置,调用stopSelf()即可。
(2)Service是否在主线程中?
主线程!可以在Activity和Service中分别打印当前线程ID,会发现两者相同。
Thread.currentThread().getId();
IntentService
由Activity来停止Service的运行,并不可取。因为当前Activity并不知道,Service是否还被其他调用者使用。同时,由于处于主线程,如果Service来处理耗时任务,则会造成ANR(Application No Response)。为了解决这两个问题,Android提供了IntentService。
(当然,也在Service中使用线程和连接计数器来规避这两个问题。)
IntentService使用非常方便。当任务完成后,会自动停止,且任务在子线程中执行。因此,跟AsynTask类似。
创建一个自定义的IntentService,仅需要继承android.app.IntentService,并实现抽象方法protected void onHandleIntent(Intent intent),该方法将在线程中完成所有任务。类似于AsynTask的doBackground。
public class myIntentService extends IntentService { private final String TAG=getClass().getName(); public myIntentService() { super("myIntentService"); } @Override protected void onHandleIntent(Intent intent) { //TODO Log.i(TAG, "onHandleIntent"); } @Override public void onCreate() { Log.i(TAG, "onCreate"); super.onCreate(); } @Override public void onDestroy() { Log.i(TAG, "onDestroy"); super.onDestroy(); }}
IntentService需要使用startService类启动。
intent=new Intent(this,myIntentService.class);startService(intent);
而启动后,将依次触发IntentService的以下生命周期监听方法。
onCreateonHandleIntentonDestroy
以上,都是在同一进程中的service访问方法。
当然,Service也可以跨进程访问,通常使用AIDL的方式。将在单独的篇幅中进行介绍。
- Android四大组件(Service篇)
- Android四大组件----Service
- Android四大组件---Service
- android四大组件service
- android四大组件---service
- android四大组件---Service
- Android四大组件-Service
- Android四大组件:Service
- (Android四大组件)---Service
- Android 四大组件Service
- Android开发四大组件之Service(详解篇)
- Android开发四大组件之Service(实例篇)
- Android开发四大组件之Service(详解篇)
- 谈Android四大组件之Service篇
- Android四大组件之一Service(服务)
- android四大组件之服务(Service)
- Android四大组件之Service(二)
- 【Android】四大组件(3)Service
- Lua(2)
- 正则表达式中 test、exec、match 方法区别
- 基于windows平台Git+GitHub+Hexo搭建个人博客(一)
- 1451:幸运数字
- 我的随笔-感慨于博客专家的认证
- Android四大组件(Service篇)
- Zookeeper系统模型
- js基础-正则表达式★★★
- Realm For Android详细教程
- [PAT]1016. Phone Bills (25)@Java
- Adaboost 算法的原理与推导
- 【MySQL】RPM包安装
- 数据结构——单循环链表一部分功能的C语言实现
- 1687:字符串比较