android 如何使用Service

来源:互联网 发布:网络变压器厂商 编辑:程序博客网 时间:2024/06/15 23:53

最近还一直在搞xmpp即时通讯,其中涉及最多的还是Service和BroadcastReceiver。我们不妨带着以下问题去深究。

一、为什么要使用Service?
1.什么是Service
Service是Android中四大组件之一,在Android开发中起到非常重要的作用,先来看一下官方对Service的定义:
A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with it and even perform interprocess communication (IPC). For example, a service might handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background.

翻译过来就是:Service(服务)是一个没有用户界面的在后台运行执行耗时操作的应用组件。其他应用组件能够启动Service,并且当用户切换到另外的应用场景,Service将持续在后台运行。另外,一个组件能够绑定到一个service与之交互(IPC机制),例如,一个service可能会处理网络操作,播放音乐,操作文件I/O或者与内容提供者(content provider)交互,所有这些活动都是在后台进行。
Service有两种状态,“启动的”和“绑定”。
参考:http://blog.csdn.net/ryantang03/article/details/7770939

2.Service的生命周期
onCreate  onStart  onDestroy  onBind
1). 被启动的服务的生命周期:如果一个Service被某个Activity 调用 Context.startService 方法启动,那么不管是否有Activity使用bindService绑定或unbindService解除绑定到该Service,该Service都在后台运行。如果一个Service被startService 方法多次启动,那么onCreate方法只会调用一次,onStart将会被调用多次(对应调用startService的次数),并且系统只会创建Service的一个实例(因此你应该知道只需要一次stopService调用)。该Service将会一直在后台运行,而不管对应程序的Activity是否在运行,直到被调用stopService,或自身的stopSelf方法。当然如果系统资源不足,android系统也可能结束服务。
2). 被绑定的服务的生命周期:如果一个Service被某个Activity 调用 Context.bindService 方法绑定启动,不管调用 bindService 调用几次,onCreate方法都只会调用一次,同时onStart方法始终不会被调用。当连接建立之后,Service将会一直运行,除非调用Context.unbindService 断开连接或者之前调用bindService 的 Context 不存在了(如Activity被finish的时候),系统将会自动停止Service,对应onDestroy将被调用。
3). 被启动又被绑定的服务的生命周期:如果一个Service又被启动又被绑定,则该Service将会一直在后台运行。并且不管如何调用,onCreate始终只会调用一次,对应startService调用多少次,Service的onStart便会调用多少次。调用unbindService将不会停止Service,而必须调用 stopService 或 Service的 stopSelf 来停止服务。
4). 当服务被停止时清除服务:当一个Service被终止(1、调用stopService;2、调用stopSelf;3、不再有绑定的连接(没有被启动))时,onDestroy方法将会被调用,在这里你应当做一些清除工作,如停止在Service中创建并运行的线程。

********************************************

特别注意:
a.你应当知道在调用 bindService 绑定到Service的时候,你就应当保证在某处调用 unbindService 解除绑定(尽管 Activity 被 finish 的时候绑定会自动解除,并且Service会自动停止);
b.你应当注意 使用 startService 启动服务之后,一定要使用 stopService停止服务,不管你是否使用bindService;
c.同时使用 startService 与 bindService 要注意到,Service 的终止,需要unbindService与stopService同时调用,才能终止 Service,不管 startService 与 bindService 的调用顺序,如果先调用 unbindService 此时服务不会自动终止,再调用 stopService 之后服务才会停止,如果先调用 stopService 此时服务也不会终止,而再调用 unbindService 或者 之前调用 bindService 的 Context 不存在了(如Activity 被 finish 的时候)之后服务才会自动停止;
d.当在旋转手机屏幕的时候,当手机屏幕在“横”“竖”变换时,此时如果你的 Activity 如果会自动旋转的话,旋转其实是 Activity 的重新创建,因此旋转之前的使用 bindService 建立的连接便会断开(Context 不存在了),对应服务的生命周期与上述相同。
e.在 sdk 2.0 及其以后的版本中,对应的 onStart 已经被否决变为了 onStartCommand,不过之前的 onStart 任然有效。这意味着,如果你开发的应用程序用的 sdk 为 2.0 及其以后的版本,那么你应当使用 onStartCommand 而不是 onStart。

********************************************

3.Service的启动方式
1).startService 启动的服务 主要用于启动一个服务执行后台任务,不进行通信。停止服务使用stopService
2).bindService 启动的服务 该方法启动的服务要进行通信。停止服务使用unbindService
3).startService 同时也 bindService 启动的服务 停止服务应同时使用stepService与unbindService

4.Service 与 Thread 的区别
1). Thread:Thread 是程序执行的最小单元,它是分配CPU的基本单位。可以用 Thread 来执行一些异步的操作。
2). Service:Service 是android的一种机制,当它运行的时候如果是Local Service,那么对应的 Service 是运行在主进程的 main 线程上的。如:onCreate,onStart 这些函数在被系统调用的时候都是在主进程的 main 线程上运行的。如果是Remote Service,那么对应的 Service 则是运行在独立进程的 main 线程上。因此请不要把 Service 理解成线程,它跟线程半毛钱的关系都没有!
既然这样,那么我们为什么要用 Service 呢?其实这跟 android 的系统机制有关,我们先拿 Thread 来说。Thread 的运行是独立于 Activity 的,也就是说当一个 Activity 被 finish 之后,如果你没有主动停止 Thread 或者 Thread 里的 run 方法没有执行完毕的话,Thread 也会一直执行。因此这里会出现一个问题:当 Activity 被 finish 之后,你不再持有该 Thread 的引用。另一方面,你没有办法在不同的 Activity 中对同一 Thread 进行控制。
举个例子:如果你的 Thread 需要不停地隔一段时间就要连接服务器做某种同步的话,该 Thread 需要在 Activity 没有start的时候也在运行。这个时候当你 start 一个 Activity 就没有办法在该 Activity 里面控制之前创建的 Thread。因此你便需要创建并启动一个 Service ,在 Service 里面创建、运行并控制该 Thread,这样便解决了该问题(因为任何 Activity 都可以控制同一 Service,而系统也只会创建一个对应 Service 的实例)。
因此你可以把 Service 想象成一种消息服务,而你可以在任何有 Context 的地方调用 Context.startService、Context.stopService、Context.bindService,Context.unbindService,来控制它,你也可以在 Service 里注册 BroadcastReceiver,在其他地方通过发送 broadcast 来控制它,当然这些都是 Thread 做不到的。
参考:http://www.cnblogs.com/newcj/archive/2011/05/30/2061370.html
二、如何使用service?

MainActivity

package com.app.servicebindingbroadcast;import android.content.BroadcastReceiver;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.content.ServiceConnection;import android.os.IBinder;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import com.app.servicebindingbroadcast.service.TestService;public class MainActivity extends AppCompatActivity {    private static final String TAG=MainActivity.class.getName();    private ServiceBroadcastReceiver receiver=new ServiceBroadcastReceiver();    private  TestService.MBinder binder;    private BindServiceConnection bindServiceConnection;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        IntentFilter filter=new IntentFilter();        filter.addAction(TestService.ACTION_NAME_SERVICE);        registerReceiver(receiver,filter);        setContentView(R.layout.activity_main);    }    public void onBtnClick(View v){        Intent intent=new Intent(MainActivity.this,TestService.class);        switch (v.getId()){            case R.id.main_service_start:                Log.i(TAG,"--onBtnClick--开启服务");                startService(intent);                break;            case R.id.main_service_stop:                Log.i(TAG,"--onBtnClick--关闭服务");                stopService(intent);                break;            case R.id.main_service_bind:                Log.i(TAG,"--onBtnClick--绑定服务");                if(bindServiceConnection==null){                    bindServiceConnection= new BindServiceConnection();                }                bindService(intent,bindServiceConnection,BIND_AUTO_CREATE);                break;            case R.id.main_service_bindun:                Log.i(TAG,"--onBtnClick--解绑服务");                if(bindServiceConnection!=null&&binder!=null){                    unbindService(bindServiceConnection);                    bindServiceConnection=null;                    binder=null;                }else{                    Log.i(TAG,"--onBtnClick--服务没有绑定,解绑无效");                }                break;        }    }    /**     * 服务运行状态的广播接收者     */    private class ServiceBroadcastReceiver extends BroadcastReceiver {        @Override        public void onReceive(Context context, Intent intent) {            String text=intent.getStringExtra(TestService.KEY_SERVICE_STATUS);            Log.i(MainActivity.class.getName(),"##打印###"+text);        }    }    private class  BindServiceConnection implements ServiceConnection{        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            binder=(TestService.MBinder)service;            binder.donSomeThing();        }        @Override        public void onServiceDisconnected(ComponentName name) {        }    }}

TestService

package com.app.servicebindingbroadcast.service;import android.app.Service;import android.content.Intent;import android.content.ServiceConnection;import android.os.Binder;import android.os.IBinder;import android.util.Log;/** * package_name com.app.servicebindingbroadcast.service * Created by yang on 2016/8/2. */public class TestService extends Service{    private static final String TAG=TestService.class.getName();    public static final String ACTION_NAME_SERVICE="broadcast.serivce";    public static final String KEY_SERVICE_STATUS="key.service.status";    private MBinder binder;    @Override    public void onStart(Intent intent, int startId) {        super.onStart(intent, startId);        Log.i(TAG,"--service--onStart----");    }    @Override    public void onCreate() {        super.onCreate();        Log.i(TAG,"--service--onCreate----");        sendBroadcast("服务已经开启");    }    private void sendBroadcast(String msg) {        Intent intent=new Intent();        intent.putExtra(KEY_SERVICE_STATUS,msg);        intent.setAction(ACTION_NAME_SERVICE);        sendBroadcast(intent);    }    @Override    public IBinder onBind(Intent intent) {        Log.i(TAG,"--service--onBind----");        sendBroadcast("服务已经绑定");        binder=new MBinder();        return binder;    }    public class MBinder extends Binder {        public void donSomeThing(){            Log.i(TAG,"--donSomeThing----");            sendBroadcast("--后台正在执行操作---");        }    }    @Override    public boolean onUnbind(Intent intent) {        Log.i(TAG,"--service--onUnbind----");        sendBroadcast("服务已经解绑");        binder=null;        return super.onUnbind(intent);    }    @Override    public boolean bindService(Intent service, ServiceConnection conn, int flags) {        Log.i(TAG,"--service--bindService----");        sendBroadcast("服务已经解绑");        return super.bindService(service, conn, flags);    }    @Override    public void unbindService(ServiceConnection conn) {        super.unbindService(conn);        Log.i(TAG,"--service--unbindService----");        sendBroadcast("服务已经解绑");    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        Log.i(TAG,"--service--onStartCommand----");        sendBroadcast("服务已经正在运行状态");        return super.onStartCommand(intent, flags, startId);    }    @Override    public void onDestroy() {        super.onDestroy();        Log.i(TAG,"--service--onDestroy----");        sendBroadcast("服务停止");    }}manifest

0 0
原创粉丝点击