Android四大组件之Service

       俗话说的好:“一个成功的男人背后有一个了不得的女人”,如果说Activity是男人的话,那么Service非女人莫属了,正所谓:“男管外(向外参加各种活动,且提供与用户交互的可视化界面),女管内(后台运行提供某种服务)”。

        女人嘛(Service)!是一个对感情是专一的(其它的应用程序组件可以启动一个Service,即使在用户切换到另外一个应用程序后,这个Service还是一直会在后台运行),偶然会也会出轨(远程服务调用:远程服务调用就是能够提供给其他程序调用的接口,我们知道一个操作系统上面有很多个应用程序在运行,每一个运行的程序都对应着一个独立的进程,这些进程是相对独立的,默认情况下是不能实现数据的共享;在安卓平台上,我们的四大组件都运行在自己的进程里。因此它们之间是不能相互访问数据,但是在整个应用程序运行中,肯定会涉及到组件之间的数据传递,这就需要借助于远程服务)。

       女人一生中有两种比较大的状态(一个Service可以有两种形式存在):

1.少女时代一人单身过生活(Started (启动)在一个应用程序以startService() 来启动一个Service时,这个Service将处于“Started”状态。一旦启动,这个Service可以在后台一直运行下去,即使启动它的应用程序已退出。通常,一个处于“started”状态的Service完成某个功能而不会给启动它的应用程序组件返回结果。比如,这个服务(Service)可能是上载或是下载一个文件,当任务完成后,服务自行退出。)。

2.长大了结婚和男人一起生活( Bound (绑定) 当一个应用程序组件以bindService() 绑定一个Service时,这个Service处于“Bound”状态。处于“Bound”状态的Service提供了一个客户/服务(C/S)调用接口支持其它应用程序组件和它交互,比如发生请求,返回结果,或者使用IPC完成跨进程间通信。一个处于“Bound”的Service只能和与其绑定的应用程序一起运行。多个应用程序组件可以绑定到同一个Service。当所有绑定的应用程序组件都退出绑定后,被“绑定”的Service将被销毁。)。

       对于一个Service来说,它可以是“Started”,“Bound”或者同时处于两种状态。其它任一应用程序组件(比如一个Activity)都可以使用这个Service,即使其它应用程序组件是在不同的应用程序中。当然你可以把Service定义为私有的,这样其它应用程序就无法使用你定义的Service。

       要注意的是,一个Service运行在其宿主进程的主线程中--服务不会自己创建新的线程也不运行在独立的进程中(除非你特别指明)。这意味着,如果你的Service需要完成一些很耗CPU资源的操作(比如播放MP3,或者使用网络),你应该在Service中创建新的线程来完成这些工作,从而降低出现程序无响应(ANR)的风险。

      每个人(四大组件)都有自己的生命周期,看看女人(Service)的生命周期吧!小二上图:

不像是activity的生命周期回调函数,你不需要调用父类执行这些回调方法。

        Service整体的生命时间是从onCreate()调用开始,到onDestroy()方法返回为止。和Activity一样,Service在onCreate()中进行它的初始化工作,在onDestroy()中释放残留的资源。onCreate() 和 onDestroy()会被所有的Service调用,不论Service是通过startService()还是bindService()建立的Service。Service积极活动的生命时间(activelifetime)是从onStartCommand() 或onBind()被调用开始,它们各自处理由startService()或 bindService()方法传过来的Intent对象。

 

  如果Service是通过startService()开启的,那么它的活动生命周期和整个生命周期一同结束。

“Started”的Service 这个Service是由其它的应用程序组件调用startService()创建的,这个service 可以在后台无限期运行直到调用 stopSelf()或者其它组件调用stopService()来停止它。当Service停止时,系统将销毁这个Service

  如果Service是通过bindService ()开启的,它们它的活动生命周期是在onUnbind()方法返回后结束。

支持“绑定”的Service 这种Service是在其它组件调用 bindService()绑定它时创建客户端,然后可以通过服务接口和Serivce通信。客户端可以调用 unbindService () 解除与Service的绑定。多个客户端可以同时绑定同一Service,当一个Service没有客户端和它绑定时,系统则销毁这个Service。

        注意:尽管一个被开启的Service是通过调用 stopSelf() 或 stopService()来停止的,没有一个对应的回调函数与之对应,即没有onStop()回调方法。所以,当调用了停止的方法,除非这个Service和客户组件绑定,否则系统将会直接销毁它,onDestory()方法会被调用,并且是这个时候唯一会被调用的回调方法。

       对于男生来说,女人的出生年月日(Service的创建,我们写一个类继承抽象类Service并实现抽象方法onBind(),重写onStart()方法来进行服务相关的业务处理;最后需要在主配置文件AndroidManifest.xml注册服务)还是很重要的。代码如下:

 

//创建一个类继承Service
public class  DemoService extends Service{
    //Service创建时调用
    @Override
    public void onCreate() {//只创建一次,重复使用
        super.onCreate();
    }

    //通过starService方法调用时被调用
    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
    }

    //通过bindService方法启动时被调用
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
 
    //调用stopService方法时执行此方法
    @Override
    public void onDestroy() {
       super.onDestroy();
    }
}

 

注册:

 

<service android:name=".SveActivity$DemoService"></service>

 

       好!这个女人了解得差不多了(我们已经创建好Service),现在我们要去约她出来(Service的启动和停止)。一般启动Service我们需要借助于其他的组件,在Activity或是其他应用程序组件可以通过传递Intent调用startService()方法来启动一个Service。一个“Started”的Service必须管理自己的生命周期,也就是说,除非系统资源不足,Android系统不终止或停止一个Service。

 

Intent intent = new Intent(this, DemoService.class);
startService(intent);//启动Service

 

 

//停止服务
stopService(intent);

 

       这里得说下,停止服务有两种停法。Service必须调用stopSelf () 方法来终止自身的运行,或者其它部件可以通过stopService () 方法来中止一个Service的运行。一旦Service被请求终止,系统将尽快销毁这个Service。但是,如果你的Service需要在onStartCommand()并行处理多个请求,那么你不应再处理完一个请求后就停止Service的运行,因为你可能还会接受到新的请求(在第一个请求处理完就结束则会终止第二个请求的执行)。为避免这种情况,你可以使用带参数的stopSelf(int) 来确保终止Service的请求总是对应于最近的请求。也就是说,在调用stopSelf(int) 时,你通过传入请求的Id (传给onStartCommand 方法的 startId )来终止对应的请求处理。那么如果Service在调用stopSelf (int) 前接受到一个新的请求,那么Id将不会匹配,因此Service也就不会结束。

       创建一个支持“绑定”的Service:

       接下来,我们要学习如何通过女人身边的人私约到以嫁人的女人(创建一个支持“绑定”的Service),也就是女人的人生第二种状态,第一种人生状态我们在讲约她出来(创Service的启动和停止)的时候已经讲过了。一个支持“绑定”的Service是指运行其它应用程序之间通过调用bindService() 来绑定到它的Service。支持“绑定”的Service在设计时通常不允许直接使用startService() 来启动它。在Activity或其它组件需要和一个Service发生交互时,你应该创建一个“绑定”的Service,在这个Service中你可以通过进程间通信接口(IPC)来提供可供其它应用程序组件使用的功能接口。

        为了创建一个支持“绑定”的Service,你需要实现onBind() 回调函数并返回一个IBind接口对象,这个对象提供了其它部分可以访问这个Service的服务接口。其它应用程序组件然后可以通过bindService () 方法获得Service的服务接口对象,然后使用这个对象的方法来调用服务。通常“绑定”的Service的运行周期和绑定它的其它应用程序组件的生命周期是一样的。绑定服务开启后,生命周期与调用者相关联.调用者挂了,服务也会跟着挂掉.不求同时生,但求同时死。因此如果这个Service不再有应用程序组件与之绑定,Android系统会自动销毁这个Service,而你自己无需停止这个Service。

       为了创建一个支持“绑定”的Service所需做的第一件事是定义可供客户端调用的服务接口。这个接口必须为一个IBinder接口,并且你的Service必须通过onBind () 返回这个接口对象。一旦客户端获得这个IBinder接口,就可以通过这个接口对象来使用服务。调用者和服务绑定在一起,调用者可以间接的调用到服务里面的方法。

多个客户端可以同时绑定到同一个Service,当一个客服端使用好所需的服务后,调用onbindService() 来解除与Service之间的绑定关系。当一个Service没有和它绑定的客户端后,Android系统销毁这个Service。

特别声明:服务混合调用的生命周期,开启服务后再去绑定服务然后再去停止服务,这时服务是无法停止了.必须先解绑服务然后再停止服务,在实际开发中会经常采用这种模式,开启服务(保证服务长期后台运行) –> 绑定服务(调用服务的方法) –> 解绑服务(服务继续在后台运行) –> 停止服务(服务停止),服务只会被开启一次,如果已经开启后再去执行开启操作是没有效果的。代码如下:

 

activity_sve.xml

 

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="绑定服务"
        android:id="@+id/button" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="取消绑定"
        android:id="@+id/button2" />

</LinearLayout>
创建一个类继承Service
package com.xhm.demo.myservice;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.Nullable;

/**
 * Created by Dell on 2017/3/11.
 * 创建一个类继承Service
 */
public class DemoService extends Service {
    private IBind iBind=new IBind();//实例化对象
    //Service创建时调用
    @Override
    public void onCreate() {//只创建一次,重复使用
        super.onCreate();
    }

    //通过starService方法调用时被调用
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    //通过bindService方法启动时被调用
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        //返回IBinder接口对象
        return iBind;
    }
    //调用stopService方法时执行此方法
    @Override
    public void onDestroy() {
        super.onDestroy();
    }
    //返回IBinder接口对象必须继承Binder
    public class IBind extends Binder {
        //这里我们写一些需要的方法,
        public void initBind(){
            //这里写一些处理逻辑业务代码
        }
    }
}
Activity.类
package com.xhm.demo.myservice;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class SveActivity extends Activity implements View.OnClickListener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sve);
        Button button1=(Button) findViewById(R.id.button);
        Button button2=(Button) findViewById(R.id.button2);
        button1.setOnClickListener(this);
        button2.setOnClickListener(this);

    }
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.button:
                Intent intent = new Intent(this, DemoService.class);
                startService(intent);//启动Service
            case R.id.button2:
                //停止服务
                unbindService(serviceConnection);
        }
    }
    //客户端组件,必须创建ServiceConnection,用来监听与service的连接
    private ServiceConnection serviceConnection=new ServiceConnection() {
        //绑定成功时调用此方法
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //既然绑定成功了,那我们可以获得接口对象了,
            DemoService.IBind md=(DemoService.IBind) service;
            //可以调用服务的方法
            md.initBind();
        }
        //绑定失败时调用此方法
        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
}

好了,初学者掌握到这些差不多了,如果想学习更深入的Service(想了解更多女人的八卦大笑),下面给出地址,

http://blog.csdn.net/guolin_blog/article/details/11952435/    Android Service完全解析,关于服务你所需知道的一切(上)                         

http://blog.csdn.net/baidu_26994091/article/details/51780052  android中Service使用详解                         

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值