Day14 Service
- IntentService
- BindService
- AIDL实现跨进程服务
- MediaPlayer
- Timer
IntentService
IntentService是继承于Service并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统Service一样,同时,当任务执行完后,IntentService会自动停止,而不需要我们去手动控制。
另外,可以启动IntentService多次,而每一个耗时操作会以工作队列的方式在IntentService的onHandleIntent回调方法中执行,并且,每次只会执行一个工作线程,执行完第一个再执行第二个,以此类推。
- 关键方法
- 注意事项
关键方法
除其他Service生命周期方法外:
* ==onHandleIntent(Intent)==
在该方法中进行耗时操作,由IntentService中封装的异步任务完成
处理异步请求的IntentService,其内有一个工作线程来处理耗时操作
内部使用了单线程池模式(所以每次只执行一个任务,完成后再进行第二个)
注意事项
创建IntentService子类时,需要提供一个==无参==的构造方法且调用:
==super(null)==
BindService
基于IBinder方式将两个组件进行绑定,然后相互传值.
如果以绑定的方式启动的服务,在解除绑定时也会自动停止服务.
需创建自定义Binder子类并通过onBind()返回
- 生命周期方法
- 使用步骤
- 绑定类型
生命周期
除其他Service生命周期方法外:
- ==
IBinder onBind(Intent)==
- 返回自定义的Binder的子类
- 返回Messenger的getBinder()
- ==
onUnBind(Intent)==
- 解除绑定时回调
- ==
onReBind(Intent)==
- 重新绑定时回调
使用步骤
bindService的过程:
* 在Service组件中,声明Binder类的子类(公共),在其子类中声明组件之间的接口方法
* 在onBind()方法中,实例化Binder子类的对象,并返回
* 在绑定服务组件端(Activity),实例化ServiceConnection接口对象
* 在ServiceConnection接口对象的onServiceConnected()方法中,将方法的第二个参数IBinder对象强转成Binder子类对象
* 在适当的位置 调用 Context.bindService()来绑定服务。
创建类,继承Service,并现实onBind()方法
在Service组件中,声明Binder类的子类(公共),在其子类中声明组件之间的接口方法
public class MyService extends Service{
public IBinder onBind(Intent intent) {
...
}
public class MyBinder extends Binder{
public void MyMethod1(){
...
}
public void MyMethod2(){
...
}
...
}
}
在onBind()方法中,实例化Binder子类的对象,并返回
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();//实例化Binder的子类,并返回
}
在绑定服务组件端(Activity),实例化ServiceConnection接口对象
在ServiceConnection接口对象的onServiceConnected()方法中,将方法的第二个参数IBinder对象强转成Binder子类对象
ServiceConnection conn=new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 绑定成功的方法
myBinder=(MyBinder) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
// 与绑定服务组件断开连接(发生的时机:由于系统原因造成了服务组件停止或销毁)
myBinder=null;
}
};
在适当的位置 调用 Context.bindService()来绑定服务。
//绑定服务组件
bindService(new Intent(getApplicationContext(),TimerService.class),
conn, BIND_AUTO_CREATE);
//BIND_AUTO_CREATE标识表示:绑定的服务组件如果不存,则会自动创建,
//注:由bindService方式启动的Service,其生命周期会受到绑定组件的影响,即当绑定组件Activity销毁时,Service也会停止
解除绑定
//解除绑定
Context.unBindService(Intent)
绑定类型
绑定服务的类型:
* ==BIND_AUTO_CREATE==
- 绑定的service不存在时,会自动创建
* ==BIND_ADJUST_WITH_ACTIVITY==
- service的优先级别与根据所绑定的Activity的重要程度有关,Activity处于前台,service的级别高
* ==BIND_NOT_FOREGROUND==
- Service永远不拥有运行前台的优先级
* ==BIND_WAIVE_PRIORITY==
- Service的优先级不会改变
* ==BIND_IMPORTANT | BIND_ABOVE_CLIENT==
- 所绑定的Activity处于前台时,Service也处于前台
- BIND_ABOVE_CLIENT 指定内存很低的情况下,运行时在终止绑定的Service之前终止Activity
AIDL实现跨进程服务
一种接口定义语言,用于约束两个进程间的通讯规则,供编译器生成代码
个人理解:
为了能使两个进程(应用)之间通信,二者需要持有同一个通讯工具,即通过AIDL文件定义的接口
当一个应用使用AIDL文件时,会自动生成其定义的java接口,通过这个接口实现与目标服务的通信接驳
- AIDL支持的数据类型
- 使用方法案例
AIDL支持的数据类型
AIDL默认支持的类型:
- java基本类型:==
int==、==long==、==boolean==、==float==、==double==、==char== - 引用类型及集合:==
String[]==、==List==、==Map==
使用方法案例
使用步骤概览
服务端:
- 服务端创建.aidl文件和声明接口
- 创建类,继承Service,并实现onBind方法
- 在Service类中定义aidl中声明接口的Stub对象,并实现aidl接口中声明的方法
- 在onBind方法中返回Stub对象
- 在AndroidManifest.xml中注册Service并声明其Action
客户端:
- Context.bindService(new Intent(接口的类名,ServiceConnection,int)
- 定义ServiceConnection对象
onServiceConnected(ComponentName,IBinder)
onServiceDisconnected()
//aidl接口对象=AIDLService.Stub.asInterface(server)
- 在Activity定义aidl接口对象
样例
IRemoteService.AIDL
package com.qf.aidl;
interface IRemoteService{
void print(String msg);
String getName();
}
- RemoteService.java
public class RemoteSerice extends Service {
//2.1 实例化.aidl接口的Stub对象
private IRemoteService.Stub stub=new IRemoteService.Stub() {
@Override
public void print(String msg) throws RemoteException {
Log.i("debug", "--RemoteSerice---"+msg);
}
@Override
public String getName() throws RemoteException {
return "RemoteSerice";
}
};
@Override
public IBinder onBind(Intent intent) {
return stub;//2.2 返回aidl接口的Stub对象
}
}
- (Client)
//声明aild接口对象
IRemoteService remoteService;
//实例化绑定组件之间的通信接口
ServiceConnection conn=new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//将第二个参数转化为.aidl接口对象
remoteService=IRemoteService.Stub.asInterface(service);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//绑定其它应用的Service组件,在绑定成功之后,将返回的Stub对象转化为aidl接口对象
bindService(new Intent("com.qf.serivce04_aidl_server.RemoteSerice"),
conn, BIND_AUTO_CREATE);
}
MediaPlayer
用于播放音乐和视频文件
构造方法:==MediaPlayer()==
通过静态方法(create)构造会直接进入prepared状态
通过静态方法构造:==MediaPlayer create(Context context, int resid)==
常用方法
- ==
setDataSource(String path)== 设置媒体源 - ==
setLooping(boolean)== 设置是否循环播放 - ==
prepare()== 预处理,调用start()前必须先调用此方法 - ==
start()== 开始播放 - ==
pause()==暂停播放 - ==
stop()== 停止播放 - ==
isPlaying()== 是否正在播放 - ==
reset()== 重置播放器,进入idle空闲状态 - ==
release()== 释放资源 - ==
getDuration()== 获取播放文件的总时长,单位:毫秒 - ==
getCurrentPosition()== 获取当前播放的位置 - ==
seekTo(int position)== 定位到指定的播放时间
Timer定时器
按排一段定时任务在指定的时间执行,对于提醒相关的任务,应该设置重复间隔时间
关键方法
- ==
schedule(TimerTask task, Date when)== 按排任务在指定时间执行 - ==
schedule(TimerTask task, long delay)== 按排任务延迟多少毫秒之后执行 - ==
schedule(TimerTask task, long delay, long period)== 按排任务在延迟多个毫秒后执行,并间隔多少毫秒后重复 - ==
cancel()== 取消定时器
TimerTask 定时任务
TimerTask 定时任务类,是实现Runnable接口的抽象类
样例
timer.schedule(new TimerTask(){
@Override
public void run() {
// TODO 在指定的时间执行的任务
NotificationCompat.Builder builder=
new NotificationCompat.Builder(getApplicationContext());
builder.setSmallIcon(android.R.drawable.ic_menu_today)
.setContentTitle("提醒")
.setContentText("时间了,该起床了....")
.setTicker("时间了,该起床了....")
.setDefaults(Notification.DEFAULT_SOUND)
.setOngoing(true);
notifyMgr.notify(2, builder.build());
}
},10*1000, 5*1000);
本文详细介绍了Android中的IntentService、BindService以及AIDL实现跨进程服务。讲解了IntentService的工作原理,如何创建和使用;阐述了BindService的生命周期、绑定过程以及不同类型的绑定服务。同时,还探讨了AIDL的基本概念、数据类型支持和使用案例。此外,还涵盖了MediaPlayer的常用方法以及Timer定时器的使用。
379

被折叠的 条评论
为什么被折叠?



