分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow
也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!
今天我们就来介绍一下Android中的四大组件中的服务Service,说到Service,
它分为本地服务和远程服务:区分这两种服务就是看客户端和服务端是否在同一个进程中,本地服务是在同一进程中的,远程服务是不在同一个进程中的。
开启服务也有两种方式,一种是startService(),他对应的结束服务的方法是stopService(),另一种是bindService(),结束服务的是unBindService(),这两种方式的区别就是:当客户端Client使用startService方法开启服务的时候,这个服务和Client之间就没有联系了,Service的运行和Client是相互独立的,想结束这个服务的话,就在服务本身中调用stopSelf()方法结束服务。而当客户端Client使用bindService方法开始服务的时候,这个服务和Client是一种关联的关系,他们之间使用Binder的代理对象进行交互,这个在后面会详细说到,要是结束服务的话,需要在Client中和服务断开,调用unBindService方法。
在这里我们只做bindService方式的研究,而startService方式比较独立和简单,这里就不做演示了。
首先来说一下本地服务:
本地服务很简单的,就是Client和这个服务在同一个进程中:
先来看一下代码吧:
下面这张图是项目的结构图:
为了方便数据的访问,这里定义一个数据的访问接口:
- package com.nativeservice.demo;
- /**
- * 访问接口
- * @author weijiang204321
- */
- public interface IStudent {
- /**
- * 通过no访问name
- * @param no
- * @return
- */
- public String getNameByNumber(int no);
- }
下面再来看一下StudentService的代码:
- package com.nativeservice.demo;
- import android.app.Service;
- import android.content.Intent;
- import android.os.Binder;
- import android.os.IBinder;
- /**
- * 定义的服务Service
- * @author weijiang204321
- */
- public class StudentService extends Service{
- //名称
- public static String[] nameAry = {"张飞","李小龙","赵薇"};
- /**
- * 通过no获取name
- * @param no
- * @return
- */
- private String getNameByNo(int no){
- if(no>0 && no<4)
- return nameAry[no-1];
- return null;
- }
- @Override
- public IBinder onBind(Intent arg0) {
- return new StudentBinder();
- }
- /**
- * 自定义的Binder对象
- * @author weijiang204321
- *
- */
- private class StudentBinder extends Binder implements IStudent{
- @Override
- public String getNameByNumber(int no) {
- return getNameByNo(no);
- }
- }
- }
下面看一下Client代码:
- package com.nativeservice.demo;
- import android.app.Activity;
- import android.content.ComponentName;
- import android.content.Intent;
- import android.content.ServiceConnection;
- import android.os.Bundle;
- import android.os.IBinder;
- import android.os.Looper;
- import android.widget.Toast;
- /**
- * 测试Service
- * @author weijiang204321
- *
- */
- public class MainActivity extends Activity {
- private IStudent student;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- //开启查询名称的服务
- Intent service = new Intent(this,StudentService.class);
- bindService(service,new StudentConnection(),BIND_AUTO_CREATE);
- //延迟2s在显示查询的内容,不然开启服务也是需要时间的,如果不延迟一段时间的话,student对象为null;
- new Thread(){
- @Override
- public void run(){
- try {
- Thread.sleep(2*1000);
- Looper.prepare();
- Toast.makeText(getApplicationContext(), student.getNameByNumber(1), Toast.LENGTH_LONG).show();
- Looper.loop();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }.start();
- }
- /**
- * 自定义的服务连接connection
- * @author weijiang204321
- *
- */
- private class StudentConnection implements ServiceConnection{
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- student = (IStudent)service;
- }
- @Override
- public void onServiceDisconnected(ComponentName name) {
- }
- }
- }
StudentConnection,必须实现两个方法,这两个方法见名思议,一个是连接时调用的方法,一个是断开连接时的方法,在开始连接的方法onServiceConnected中传回来一个IBinder对象,这个时候需要将其转化一下,这个就是为什么要在开始的时候定义一个IStudent接口,在这里访问数据就方便了,同时在Client代码中要做个延迟的操作来访问数据,因为开启服务,连接这个过程是需要时间的,所以在这里就延迟了2s,这里只是为了能够正常显示数据,才这么做的,不然student对象是为null的,当然要根据自己的实际情况操作。最后还要在AndroidMainfest.xml中配置Service: