Android笔记三十一.Service综合实例(一)

综合实例1:访问本地Service服务
    a)通过Context的startService()方法启动和停止Service ;
    b)通过Context的bindService()方法绑定和解除绑定 ;
           实现本地Activity获取service服务,并与之通信,获取service相关数据。
技术分享
技术分享
1.源码
(1)src/MainActivity.java:应用程序主Acitvity
功能:获取界面组件并为相关组件注册事件监听器(内部类形式)、启动指定Service、与Service通信
开发核心步骤:
         a)实例化两个Intent对象(Intent service),用于指定启动本地哪个Service服务;
         b)   对于非绑定式Service:
            >调用Context.startService(Intent service)启动非绑定式Service;
            >调用Context.stopService(Intent intent)关闭Service; 
                对于绑定式Service:
            >调用Context.bindService(Intent service, ServiceConnection conn, int flags) 启动绑定式Service;   
            >调用unbindService(ServiceConnection conn)解除与Servcie的绑定并关闭Service;
            >创建一个ServcieConnection对象,用于监听访问者与Service之间的连接情况
                   (1)连接成功:回调该ServiceConnection对象的onServiceConnected(ComponentName name,IBinder service)方法
                   (2)连接失败:回调其onServiceDisconnected(ComponentName name)方法
               其中,onServiceConnected方法用于获取Service的onBind()方法返回的IBinder对象,通过该对象我们可以实现与Service的通信。
<span style="font-family:Times New Roman;font-size:18px;">package com.example.servicetest1;
import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
 private Button startService;
 private Button stopService;
 private Button bindService;
 private Button unbindService;
 private Button getData;
 private MyBindService.MyIBinder binder;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //a.获取界面组件
        startService = (Button)findViewById(R.id.start);
        stopService = (Button)findViewById(R.id.stop);
        bindService = (Button)findViewById(R.id.bind);
        unbindService = (Button)findViewById(R.id.unbind);
        getData = (Button)findViewById(R.id.get);
        //b.为组件注册同一个监听器
        MyEvent Listener = new MyEvent();	 //实例化一个事件监听器
        startService.setOnClickListener(Listener);	//为组件注册监听器对象
        stopService.setOnClickListener(Listener);
        bindService.setOnClickListener(Listener);
        unbindService.setOnClickListener(Listener);
        getData.setOnClickListener(Listener);
    }
   
    /*1.事件处理内部类
     * 通过获取视图组件(v)并判定组件ID,来响应具体组件*/
    public class MyEvent implements OnClickListener
    {
     //a.设置启动指定Service的"意图"
     Intent intent1 = new Intent("com.jiangdongguo.MyService");
  Intent intent2 = new Intent("com.jiangdongguo.MyBindService");
  //b.启动指定的service
     public void onClick(View v)
  {
   switch (v.getId())
   {
    //(1)启动普通Service
    case R.id.start:
     startService(intent1);	//启动"intent"指定的Service服务
     break;
    //(2)关闭普通Service
    case R.id.stop:
     stopService(intent1);	//关闭"intent"指定的Service服务
     break;
    //(3)启动并绑定Service
    case R.id.bind:
     bindService(intent2, conn, Service.BIND_AUTO_CREATE);
     break;
    //(4)解除与Service绑定
    case R.id.unbind:
     unbindService(conn);
     break;
    //(5)从service服务获取数据
    case R.id.get:
     Toast.makeText(MainActivity.this,"从Service读取到的数据为:count="+Integer.toString(binder.getCount()), Toast.LENGTH_SHORT).show();
     break;
    default:
     break;
   }
  }
     
    }
    /*2.ServcieConnection匿名内部类:创建一个ServcieConnection对象
  * 该内部类的对象用于监听访问者与Service之间的连接情况
  * (1)连接成功:回调该ServiceConnection对象的onServiceConnected(ComponentName name,IBinder service)方法
  * (2)连接失败:回调其onServiceDisconnected(ComponentName name)方法*/
 private ServiceConnection conn = new  ServiceConnection()
 {
  //a.连接服务成功:该方法用于获取Service返回的IBinder对象,用于与Service进行通信
  public void onServiceConnected(ComponentName name, IBinder service)
  {
   System.out.println("---MainActivity's onServiceConnected invoked!---");
   binder = (MyBindService.MyIBinder)service;	//获取Service返回的IBinder对象
  }
  //b.连接服务失败:提示失败
  public void onServiceDisconnected(ComponentName name) {
   System.out.println("---MainActivity's onServiceDisconnected invoked!---");
   Toast.makeText(MainActivity.this, "与Service绑定失败,请重试。", Toast.LENGTH_SHORT).show();
  }
 };
}</span>
(2)src/MyService.java:非绑定式Service服务
功能:继承Service的子类,实现当访问者调用相关的Context.Xxxx()方法回调的相关方法
开发核心步骤:
        a)重写Context.startService(Intent service)启动Service回调的方法
                >onCreate():完成初始化或相关业务逻辑代码
                >onStartCommand(Intent intent, int flags, int startId):完成相关业务逻辑代码
        b)重写Context.stopService(Intent intent)关闭Service回调的方法
                >onDestory():关闭Service服务
注意:onBind方法为抽象方法,在代码中必须实现。但由于访问者与Service服务无绑定关系,不能通信,因此无需具体实现该方法,只需返回null即可。
<span style="font-family:Times New Roman;font-size:18px;">package com.example.servicetest1;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class MyService extends Service {
 /*1.onBind方法
  * service用于返回一个IBinder对象给客户端方便通信
  * 如果是访问者通过Context.startService启动该Service,则返回为空
 */
 @Override
 public IBinder onBind(Intent arg0) {
  System.out.println("---MyService’s onBind invoked!---");
  return null;
 }
 /*2.onCreate方法
  * 当Service启动后,自动调用该方法,用于初始化
  * */
 public void onCreate() {
  System.out.println("---MyService’s onCreate invoked!---");
  super.onCreate();
 }
 /*3.onStartCommand方法
  * 每次访问者调用startService方法启动该Service时都会回调该方法*/
 public int onStartCommand(Intent intent, int flags, int startId) {
  System.out.println("---MyService’s onStartCommand invoked!---");
  return super.onStartCommand(intent, flags, startId);
 }
 /*4.onDestroy方法
  * 当访问者调用Context.stopService方法后,调用该方法关闭Service服务
  * */
 public void onDestroy() {
  System.out.println("---MyService’s onDestory invoked!---");
  super.onDestroy();
 }
}</span>
(3)src/MyBindService.java:绑定式Service服务
功能:继承Service的子类,实现当访问者调用相关的Context.Xxxx()方法回调的相关方法
开发核心步骤:
        a)重写Context.bindService(Intent service, ServiceConnection conn, int flags) 启动Service回调的方法
                >onCreate():完成初始化或相关业务逻辑代码
                >IBinder onBind(Intent arg0):用于返回一个IBinder对象给访问者
        b)实现一个内部类,该类继承于Binder类并提供相关方法,使访问者通过获得的IBinder对象        
            调用该类成员方法,从而实现访问者与Service服务之间的通信。
            如:public class MyIBinder extends Binder
                     {
                            /*.....成员方法或变量......*/
                     }
        c)重写Context.unbindService( ServiceConnection conn) 关闭Service回调的方法
                >onUnbind(Intent intent):解除访问者与Service服务的绑定
                >onDestory():关闭Service服务
注意:onBind方法为抽象方法,在代码中必须实现。将客户端与Service服务绑定,目的就是为了实现两者之间的通信,而他们的通信媒介就IBinder对象,访问者可以通过IBinder对象调用Service子类的IBinder内部类中的成员方法,从而实现对Service服务的数据访问。

<span style="font-family:Times New Roman;font-size:18px;">package com.example.servicetest1;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
public class MyBindService extends Service {
 private int count=0;
 private boolean threadFlag=true;	//结束线程标志
 MyIBinder bind = new MyIBinder();	//实例化一个Binder对象,用于被onBind方法返回给访问者
 /*0.Binder子类
  * 其对象用于与访问者通信,访问者通过调用IBinder子类中的方法获取Service中的数据*/
 public class MyIBinder extends Binder
 {
  //自定义成员方法,用于返回Service中的数据
  public int getCount()
  {
   return count;
  }
 }
 /*1.onBind方法
  * service用于返回一个IBinder对象给客户端方便通信
  * 如果是访问者通过Context.startService启动该Service,则返回为空
 */
 @Override
 public IBinder onBind(Intent arg0) {
  System.out.println("---MyService’s onBind invoked!---");
  return bind;
 }
 /*2.onCreate方法
  * 当Service启动后,自动调用该方法,用于初始化
  * */
 public void onCreate() {
  System.out.println("---MyService’s onCreate invoked!---");
  //创建一个线程,用于按一定时间间隔更新count的值
  new Thread(){
   public void run()
   {
    while(threadFlag)	//默认为true
    {
     try
     {
      Thread.sleep(500);
     }
     catch (InterruptedException e)
     {
      e.printStackTrace();
     }
     count++;
    }
   }
  }.start();
  super.onCreate();
 }
 /*3.onStartCommand方法
  * 每次访问者调用startService方法启动该Service时都会回调该方法*/
 public int onStartCommand(Intent intent, int flags, int startId) {
  System.out.println("---MyService’s onStartCommand invoked!---");
  return super.onStartCommand(intent, flags, startId);
 }
 /*4.onDestroy方法
  * 当访问者调用Context.stopService方法后,调用该方法关闭Service服务
  * */
 public void onDestroy() {
  System.out.println("---MyService’s onDestory invoked!---");
  threadFlag=false;
  super.onDestroy();
 }
 /*5.onUnbind方法
  * 当访问者调调用Context.unBind()方法后,调用该方法与Service解除绑定*/
 public boolean onUnbind(Intent intent) {
  System.out.println("---MyService’s onUnbind invoked!---");
  return super.onUnbind(intent);
 }
 
}</span>
注意:在绑定式Service服务中,我们主要是通过线程来处理耗时任务。这里就牵扯到一个问题,就是当我们退出应用程序后,子线程却还是在运行的,它并没有结束,这样子线程就会成为一个孤儿线程,很容易被系统杀死,从而导致任务失败。为了解决这个问题,我们为子线程设置一个条件标志threadFlag,当程序调用onDestory结束service服务时,顺便将子线程结束。
2.效果演示
(1)非绑定式
技术分享

(2)绑定式
技术分享
(3)界面效果
技术分享
技术分享
3.源码分析
(1)非绑定式
    每当Service被创建时会回调onCreate()方法,每次Service被启动时都会回调onStartCommand()方法,多次启动一个已有的Service组件将不会再回调onCreate()方法,但每次启动时都会回调onStartCommand()方法。
(2)绑定式
    绑定服务的执行过程:执行单击事件方法根据Intent找到相应的Service类,并初始化该类调用Service的onCreate()方法调用该类的onBind()方法调用onServiceConnected()方法。 多次单击绑定服务按钮,并不会重复执行绑定方法。一旦解绑,调用onunBind()方法,然后自动销毁。
技术分享
技术分享
注意:
a)未启动Service而直接停止Service不起作用,但未绑定Service而先解绑Service则程序出错,强制退出;
b)若该Service处于绑定状态下,该Service不会被停止即单击停止按钮不起作用,当单击解绑Service按钮时,它会先解除绑定随后直接销毁;
c)若在解除之前,没有单击停止Service,则只解绑而不会销毁。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。