service常见问题

一、生命周期

  图1中,左边为startService()方式启动的service,右边为bindService()方式启动的service。该图来自于android SDK官方文档。

                                              
                                                                         图1   两种方式启动的service的生命周期

 

    一般情况下,我们使用startService(Intent service)来启动一个服务,但这种情况下无法得到Service对象的引用,通过Android bindService方法启动服务则可以实现此功能。

    startService与bindService的重要区别还体现在
    ①多次(点击)bindService相应的button,或多次调用bindService()方法,并不会重复绑定,即onBind方法只会调用一次。

   而多次调用startService()后,onStartCommand()方法会被重复调用!

二、代码示例

 1:调用者

  1. package com.zhf.local;  
  2.    
  3. import android.app.Activity;  
  4. import android.content.ComponentName;  
  5. import android.content.Context;  
  6. import android.content.Intent;  
  7. import android.content.ServiceConnection;  
  8. import android.os.Bundle;  
  9. import android.os.IBinder;  
  10.    
  11. /** 
  12.  * 此例的目的就是拿到MyService的引用,从而可以引用其内部的方法和变量 
  13.  *  
  14.  * @author Administrator 
  15.  *  
  16.  */  
  17. public class LocalServiceActivity extends Activity {  
  18.     /** Called when the activity is first created. */  
  19.     private MyService myService;  
  20.    
  21.     @Override  
  22.     public void onCreate(Bundle savedInstanceState) {  
  23.         super.onCreate(savedInstanceState);  
  24.         setContentView(R.layout.main);  
  25.    
  26.         Intent intent = new Intent(this, MyService.class);  
  27.         bindService(intent, connection, Context.BIND_AUTO_CREATE);  
  28.     }  
  29.    
  30.     private ServiceConnection connection = new ServiceConnection() {  
  31.    
  32.         @Override  
  33.         public void onServiceDisconnected(ComponentName name) {  
  34.             myService = null;  
  35.         }  
  36.    
  37.         @Override  
  38.         public void onServiceConnected(ComponentName name, IBinder service) {  
  39.             myService = ((MyService.MyBinder) service).getService();  
  40.             System.out.println("Service连接成功");  
  41.             // 执行Service内部自己的方法  
  42.             myService.excute();  
  43.         }  
  44.     };  
  45.    
  46.     protected void onDestroy() {  
  47.         super.onDestroy();  
  48.         unbindService(connection);  
  49.     };  
  50. }  

2:服务者

  1. package com.zhf.local;  
  2.    
  3. import android.app.Service;  
  4. import android.content.Intent;  
  5. import android.os.Binder;  
  6. import android.os.IBinder;  
  7.    
  8. public class MyService extends Service {  
  9.     private final IBinder binder = new MyBinder();  
  10.    
  11.     @Override  
  1. //生成的binder将自动返回给onServiceConnection的第二个参数  
  1. public IBinder onBind(Intent intent) {  
  2.     return binder;  
  3. }  
  1.     //通过继承Binder的方式来获得IBinder   
  2.     public class MyBinder extends Binder {  
  3.         MyService getService() {  
  4.             return MyService.this;  
  5.         }  
  6.     }  
  7.    
  8.     public void excute() {  
  9.         System.out.println("通过Binder得到Service的引用来调用Service内部的方法");  
  10.     }  
  11.    
  12.     @Override  
  13.     public void onDestroy() {  
  14.         // 当调用者退出(即使没有调用unbindService)或者主动停止服务时会调用  
  15.         super.onDestroy();  
  16.     }  
  17.    
  18.     @Override  
  19.     public boolean onUnbind(Intent intent) {  
  20.         // 当调用者退出(即使没有调用unbindService)或者主动停止服务时会调用  
  21.         System.out.println("调用者退出了");  
  22.         return super.onUnbind(intent);  
  23.     }  
  24. }  

方法过程如下:

Intent intent = new Intent(MainActivity.this,BindService.class)

->新建了BindService对象

->新建了MyBinder对象

->bindService(intent, conn, Context.BIND_AUTO_CREATE);

->onBind()函数 

 -----传递MyBinder对象

->onServiceConnected()

--> 通过传递的Binder对象获取刚刚和Binder对象对应的BindService 对象  -

->调用Service中定义的方法。

    这个其中必须通过Binder对象,因为是通过Binder对象来传递的,通过Binder对象获取Service对象,然后获取所需的服务,所以Service必须实现Binder,以便传递和使用。

三、常见问题

1. 退出activity时出现android.app.serviceConnectionLeaked错误

解决:尽管有些人认为不需关注这个错误,但毕竟是个Error!而且看起来和内存有关,长期不关注可能出现异常诡异问题。总之,是由于在activity销毁的时候,没有调用unbindService()导致。

2. onServiceDisconnected()始终没有被调用到。

解决:官方文档说,“The Android system calls this when the connection to the service is unexpectedlylost, such as when the service has crashed or has been killed. This isnot called when theclient unbinds.”就是说当该service所在的进程崩溃时,才会调用该方法。

3. java.lang.IllegalArgumentException:Service not registered:com.app.MainActivity。

原因:unbind一个没有bind过的service。此时unbind会找不到相应的service。

解决方法:unbind service时,一定要提前判断是否存在该service。因此,在bind service时最好能够搞个标记。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值