今天我们就来介绍一下Android中的四大组件中的服务Service,说到Service,

它分为本地服务和远程服务:区分这两种服务就是看客户端和服务端是否在同一个进程中,本地服务是在同一进程中的,远程服务是不在同一个进程中的。

开启服务也有两种方式,一种是startService(),他对应的结束服务的方法是stopService(),另一种是bindService(),结束服务的是unBindService(),这两种方式的区别就是:当客户端Client使用startService方法开启服务的时候,这个服务和Client之间就没有联系了,Service的运行和Client是相互独立的,想结束这个服务的话,就在服务本身中调用stopSelf()方法结束服务。而当客户端Client使用bindService方法开始服务的时候,这个服务和Client是一种关联的关系,他们之间使用Binder的代理对象进行交互,这个在后面会详细说到,要是结束服务的话,需要在Client中和服务断开,调用unBindService方法。

在这里我们只做bindService方式的研究,而startService方式比较独立和简单,这里就不做演示了。


首先来说一下本地服务:

本地服务很简单的,就是Client和这个服务在同一个进程中:

先来看一下代码吧:

下面这张图是项目的结构图:

android csdn 服务 android service详解_android

为了方便数据的访问,这里定义一个数据的访问接口:



[java]  view plain copy

1. package
2.   
3. /**
4.  * 访问接口
5.  * @author weijiang204321
6.  */
7. public interface
8. /**
9.      * 通过no访问name
10.      * @param no
11.      * @return
12.      */
13. public String getNameByNumber(int
14.       
15. }


下面再来看一下StudentService的代码:



[java]  view plain copy

1. package
2.   
3. import
4. import
5. import
6. import
7.   
8. /**
9.  * 定义的服务Service
10.  * @author weijiang204321
11.  */
12. public class StudentService extends
13.   
14. //名称
15. public static String[] nameAry = {"张飞","李小龙","赵薇"};  
16.       
17. /**
18.      * 通过no获取name
19.      * @param no
20.      * @return
21.      */
22. private String getNameByNo(int
23. if(no>0 && no<4)  
24. return nameAry[no-1];  
25. return null;  
26.     }  
27.       
28. @Override
29. public
30. return new
31.     }  
32.       
33. /**
34.      * 自定义的Binder对象
35.      * @author weijiang204321
36.      *
37.      */
38. private class StudentBinder extends Binder implements
39. @Override
40. public String getNameByNumber(int
41. return
42.         }  
43.     }  
44.   
45.   
46. }





StudentService中就是定义一个访问name的方法,在onBind方法中返回Binder对象,这个就是Client和Service之间交互的关键对象

下面看一下Client代码:


[java]  view plain copy

1. package
2.   
3. import
4. import
5. import
6. import
7. import
8. import
9. import
10. import
11.   
12. /**
13.  * 测试Service
14.  * @author weijiang204321
15.  *
16.  */
17. public class MainActivity extends
18.   
19. private
20.       
21. @Override
22. protected void
23. super.onCreate(savedInstanceState);  
24.         setContentView(R.layout.activity_main);  
25. //开启查询名称的服务
26. new Intent(this,StudentService.class);  
27. new
28. //延迟2s在显示查询的内容,不然开启服务也是需要时间的,如果不延迟一段时间的话,student对象为null;
29. new
30. @Override
31. public void
32. try
33. 2*1000);  
34.                     Looper.prepare();  
35. 1), Toast.LENGTH_LONG).show();  
36.                     Looper.loop();  
37. catch
38.                     e.printStackTrace();  
39.                 }  
40.             }  
41.         }.start();  
42.     }  
43.       
44. /**
45.      * 自定义的服务连接connection
46.      * @author weijiang204321
47.      *
48.      */
49. private class StudentConnection implements
50.           
51. @Override
52. public void
53.             student = (IStudent)service;  
54.         }  
55. @Override
56. public void
57.         }  
58.           
59.     }  
60. }

在这里,用到了bindService方法,该方法的参数是:第一个参数是服务的intent,第二参数是一个ServiceConnection接口,第三个参数是启动服务的方式常量,这里最主要的就是第二个参数ServiceConnection接口,我们自己定义一个实现该接口的类。

StudentConnection,必须实现两个方法,这两个方法见名思议,一个是连接时调用的方法,一个是断开连接时的方法,在开始连接的方法onServiceConnected中传回来一个IBinder对象,这个时候需要将其转化一下,这个就是为什么要在开始的时候定义一个IStudent接口,在这里访问数据就方便了,同时在Client代码中要做个延迟的操作来访问数据,因为开启服务,连接这个过程是需要时间的,所以在这里就延迟了2s,这里只是为了能够正常显示数据,才这么做的,不然student对象是为null的,当然要根据自己的实际情况操作。最后还要在AndroidMainfest.xml中配置Service:


[html]  
    view plain 
    copy