博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android--绑定服务调用服务的方法
阅读量:7115 次
发布时间:2019-06-28

本文共 5495 字,大约阅读时间需要 18 分钟。

Service依照其启动的方式,可分为两种:

1、Started

Started的Service。通过在Application里用startService(Intent intent)方法来启动。这样的类型的Service一经启动。会在后面无休止地执行,即使启动它的Activity被Destroy掉。要停止此类型的Service,可在Service中调用stopSelf()或在Application中调用stopService(Intent intent),要不然就仅仅能等Android系统在系统资源紧张的时候把它杀掉。



2、Bound

Bound的Service。通过在Application里调用bindService()方法来启动。

该类型的Service与Application绑定在一起,一旦绑定的全部Application消失了,Android会Detroy掉该Service。也能够主动调用unbindService()方法来解绑Service。

有时候我们想在Activity中获知Service的状态,比如一个音乐播放器。Service负责音乐播放,Activity负责显示当前歌曲名和播放进度。

能够用Broadcast。这个也不失为一个解决方法。

但假设能够获取Service实例,那么就能够调用Service中自己定义的一些方法来获取Service状态了。

首先要明白的是,第一种类型的Service是无能为力的。

由于Activity与Service之间并没有相关联的接口。即使这个Service是在Activity里start的,一旦start,两者不再有关联。

一、本地Service调用。

假设Activity与Service在同一应用程序中。两者间的交互就属于本地Service调用。

可通过bindService实现。详细操作例如以下:

1、自己定义子类MyService。继承Service类

2、在MyService类中,自己定义内部类MyBinder,继承Binder类

在内部类中,依据须要交互的数据,创建一些方法,以便Activity可通过这些方法得到Service中的一些数据。或者干脆通过一个方法返回Service实例。

public class MyBinder extends Binder  {  public MyService getServiceInstance()  {  return MyService.this;  }  }
3、在Service类中,new一个MyBinder私有成员。并在onBind()方法中return一个MyBinder实例。

之所以这样做,是由于Service一旦绑定,就会回调onBind()方法,并返回一个Binder对象给Activity。详细看下一个步骤。

4、在Activity中覆写ServiceConnection接口中的onServiceConnected(ComponentName name, IBinder service)方法,

当中的service參数就是MyService类中onBind()方法返回的MyBinder对象,调用MyBinder对象的自己定义方法getServiceInstance()可得到Service实例。

以下是一个DEMO:

import android.os.Bundle;import android.os.IBinder;import android.app.Activity;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.view.Menu;import android.view.View;public class MainActivity extends Activity {	MusicInterface mi;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Intent intent = new Intent(this, MusicService.class);        //混合调用        //为了把服务所在进程变成服务进程        startService(intent);        //为了拿到中间人对象        bindService(intent, new MusicServiceConn(), BIND_AUTO_CREATE);    }    class MusicServiceConn implements ServiceConnection{		@Override		public void onServiceConnected(ComponentName name, IBinder service) {			// TODO Auto-generated method stub			mi = (MusicInterface) service;		}		@Override		public void onServiceDisconnected(ComponentName name) {			// TODO Auto-generated method stub					}    	    }    //開始播放button    public void play(View v){    	mi.play();    }    //暂停播放button    public void pause(View v){    	mi.pause();    }}
import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;public class MusicService extends Service{	@Override	public IBinder onBind(Intent intent) {		// TODO Auto-generated method stub		return new MusicController();	}			//必须继承binder。才干作为中间人对象返回	class MusicController extends Binder implements MusicInterface{		public void play(){			MusicService.this.play();		}		public void pause(){			MusicService.this.pause();		}	}		public void play(){		System.out.println("播放音乐");	}		public void pause(){		System.out.println("暂停播放");	}	}
public interface MusicInterface {	void play();	void pause();}

二、跨进程Service调用

跨进程Service调用。即在当前应用程序中。调用还有一个应用程序中的Service。

由于Android中,每一个应用程序都执行于自己的进程中,拥有独立的Dalvik虚拟机实例,因而称为跨进程调用(Inter-Process Comunication)。

可通过AIDL服务来实现。

AIDL(Android Interface Definition Language),是Android定义的一种类似Java的语言。

主要用于定义跨进程调用时。服务端跟client用于数据交互的接口。

AIDL服务并不支持全部的Java数据类型。它仅仅支持下面的几种类型:
1、Java的简单类型(int, char, boolean等)。无需import
2、String和CharSequence。无需import
3、List和Map。无需import(应当注意的是:List和Map的元素类型必须是AIDL支持的)
4、AIDL自己主动生成的接口。须要import
5、实现android.os.Parcelable接口的类。须要import
建立简单的AIDL服务的过程例如以下:
(一)服务端步骤:
1、在服务端创建AIDL文件IMyAidl.aidl
AIDL与Java代码非常相近,演示样例代码例如以下:(注意:aidl文件后缀名为.aidl)

interface IMyAidl{void print();}
创建完aidl文件后,ADT会自己主动调用aidl命令生成对应的Java文件。

可查看gen目录下是否有一个名为IMyAidl.java的文件。

假设没有,说明.aidl文件有误。



2、继承Service类,在子类中。将AIDL接口暴露出来。

这一步类似于本地Service调用,则通过onBind(Intent intent)方法返回一个IBinder对象。

演示样例代码例如以下:

public class MyService extends Service{private AidlBinder mBinder;//Stub类是上一步骤中,aidl命令生成的Java代码中的一个类//该类实现了IBinder接口和IMyAidl接口//能够通过继承该类,然后在onBind()方法中返回AidlBinder对象//如此一来。就可以通过AidlBinder对象对AIDL文件里定义的方法进行调用public class AidlBinder extends Stub{@Overridepublic void print(){System.out.println("Hello world!")//实现AIDL文件里的接口函数}}@Overridepublic void onCreate(){mBinder = new AidlBinder();//启动服务时即创建Binder对象}@Overridepublic IBinder onBind(Intent intent){return mBinder;//返回Binder对象,让client获得Binder对象}}
3、配置AndroidManifest.xml文件

(二)client步骤:

1、创建AIDL文件

client也要创建AIDL文件,并且是跟服务端全然一样的AIDL文件。

复制服务端AIDL文件就可以。

应当注意的是:AIDL文件的包名一定要跟服务端的一致。


假设client没有该包。应创建一个包,并将AIDL文件放到包下。


2、跨进程调用Service

client跨进程调用Service的方法与本地调用Service的方法差点儿相同,也是通过bindService()。

应当注意的是。调用成功后。通过ServiceConnection接口中的onServiceConnected(ComponentName name, IBinder service)方法得到服务端onBind()方法传递过来的Binder对象。

将该对象类型转化为AIDL文件里声明的接口类型,就可以调用该接口中定义的方法。


演示样例代码例如以下:

private IMyAidl mAidl;mServiceCon = new ServiceConnection(){@Overridepublic void onServiceConnected(ComponentName name, IBinder service){//将IBinder类型转化为IMyAidl类型。mAidl = IMyAidl.Stub.asInterface(service);}@Overridepublic void onServiceDisonnected(ComponentName name){}}//远程Service绑定,当中Intent的action參数是服务端在//AndroidManifest.xml文件里
标签下的
指定的字符串bindService(new Intent("com.thomas.aidlserver.action.AIDL_SERVICE"),mServiceCon, Service.BIND_AUTO_CREATE);mAidl.print();//调用AIDL文件里声明的方法
3、配置AndroidManifest.xml文件

转载地址:http://yrghl.baihongyu.com/

你可能感兴趣的文章
将不确定变成确定~Uri文本文件不用浏览器自动打开,而是下载到本地
查看>>
[PeterDLax著泛函分析习题参考解答]第4章 Hahn-Bananch 定理的应用
查看>>
【转】使用create_project.py创建cocos2d项目时出错
查看>>
【COGS】147. [USACO Jan08] 架设电话线(二分+spfa)
查看>>
ElasticSearch Aggregation
查看>>
libogg.so fro android编译方法
查看>>
ExternalInterface的简单使用方法
查看>>
iOS开发之微信聊天工具栏的封装
查看>>
Jquery 延迟加载框架
查看>>
Dijkstra算法
查看>>
Android学习笔记——保存数据到SQL数据库中(Saving Data in SQL Databases)
查看>>
MYSQL SQL Server 事务
查看>>
WinDbg 命令集锦
查看>>
主线程不能直接调用webservice方法
查看>>
CODE:BLOCK中的CreateProcess: No such file or directory
查看>>
【多线程】学习12
查看>>
MySQL 通配符学习小结
查看>>
HashMap
查看>>
采用FPGA实现音频模数转换器
查看>>
[Grunt + AngularJS] Using ng-annotate for min-safe AngularJS
查看>>