Android--绑定服务调用服务的方法
2017-07-22 17:49
363 查看
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实例。
之所以这样做,是由于Service一旦绑定,就会回调onBind()方法,并返回一个Binder对象给Activity。详细看下一个步骤。
4、在Activity中覆写ServiceConnection接口中的onServiceConnected(ComponentName name, IBinder service)方法,
当中的service參数就是MyService类中onBind()方法返回的MyBinder对象,调用MyBinder对象的自己定义方法getServiceInstance()可得到Service实例。
以下是一个DEMO:
二、跨进程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)
可查看gen目录下是否有一个名为IMyAidl.java的文件。
假设没有,说明.aidl文件有误。
2、继承Service类,在子类中。将AIDL接口暴露出来。
这一步类似于本地Service调用,则通过onBind(Intent
intent)方法返回一个IBinder对象。
演示样例代码例如以下:
1、创建AIDL文件
client也要创建AIDL文件,并且是跟服务端全然一样的AIDL文件。
复制服务端AIDL文件就可以。
应当注意的是:AIDL文件的包名一定要跟服务端的一致。
假设client没有该包。应创建一个包,并将AIDL文件放到包下。
2、跨进程调用Service
client跨进程调用Service的方法与本地调用Service的方法差点儿相同,也是通过bindService()。
应当注意的是。调用成功后。通过ServiceConnection接口中的onServiceConnected(ComponentName
name, IBinder service)方法得到服务端onBind()方法传递过来的Binder对象。
将该对象类型转化为AIDL文件里声明的接口类型,就可以调用该接口中定义的方法。
演示样例代码例如以下:
3、配置AndroidManifest.xml文件
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 { @Override public void print() { System.out.println("Hello world!")//实现AIDL文件里的接口函数 } } @Override public void onCreate() { mBinder = new AidlBinder();//启动服务时即创建Binder对象 } @Override public IBinder onBind(Intent intent) { return mBinder;//返回Binder对象,让client获得Binder对象 } }3、配置AndroidManifest.xml文件
<!-- 自己定义訪问Service所需的权限 --> <permission android:protectLevel="normal" android:name="thomas.permission.AIDL_SERVICE"/> <service android:name="com.thomas.aidlserver.MyService" android:exported="true" android:permission="thomas.permission.AIDL_SERVICE"> <!-- IntentFilter属性是不可缺少的 --> <!-- 如此一来,client才干通过该action远程调用服务端的Service --> <intent-filter> <action android:name="com.thomas.aidlserver.action.AIDL_SERVICE"/> </intent-filter> </service>(二)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() { @Override public void onServiceConnected(ComponentName name, IBinder service) { //将IBinder类型转化为IMyAidl类型。 mAidl = IMyAidl.Stub.asInterface(service); } @Override public void onServiceDisonnected(ComponentName name){} } //远程Service绑定,当中Intent的action參数是服务端在 //AndroidManifest.xml文件里<service>标签下的<intent-filter>指定的字符串 bindService(new Intent("com.thomas.aidlserver.action.AIDL_SERVICE"), mServiceCon, Service.BIND_AUTO_CREATE); mAidl.print();//调用AIDL文件里声明的方法
3、配置AndroidManifest.xml文件
<!-- 请求訪问远程Service所需的权限,该权限定义于服务端的AndroidManifest.xml文件里 --> <uses-permission android:name="thomas.permission.AIDL_SERVICE"/>
相关文章推荐
- 【黑马Android】(10)绑定的方式调用服务的方法/图片的各种操作/人脸识别
- Android启动服务和绑定服务的方法调用
- Android -- service的开启方式, start开启和绑定开启服务,调用服务的的方法, aidl调用远程服务
- Android绑定方式开始服务&调用服务当中的方法
- Android--绑定服务调用服务的方法
- android之绑定服务调用服务的方法
- Android -- service的开启方式, start开启和绑定开启服务,调用服务的的方法, aidl调用远程服务
- Android - 绑定服务调用服务里面的方法,start/bind开启服务的比较,混合方式开启服务,本地服务,远程服务,系统服务,录音API
- [android] 绑定方式开启服务&调用服务的方法
- Android中服务里面方法的调用,开启,绑定【入门】
- Android(java)学习笔记229:服务(service)之绑定服务调用服务里面的方法 (采用接口隐藏代码内部实现)
- android,aidl,绑定远程服务,调用远程服务的方法
- Androidx学习笔记(65)--- 通过绑定服务调用服务里的方法
- Android(java)学习笔记228:服务(service)之绑定服务调用服务里面的方法
- android调用C# 服务返回对象使用方法说明
- android基础笔记:服务(Service) 采用接口的方式调用本地服务的方法
- 绑定的方式调用服务的方法和采用接口方式抽取方法
- 22_绑定的方式调用服务的方法
- Android 利用广播调用服务中的方法
- Android -- service 利用广播调用服务的方法