拓展阅读:
Service启动方式: Service关闭/解除绑定: 与service通信:
- startService(intent); stopService(intent);
- bindService(intent, connection, BIND_AUTO_CREATE); unbindService(connection); binder.getXXX()
如果服务不同时支持绑定,那么通过startService()传入的intent将是应用程序组件与服务进行交互的唯一途径。
当然,如果你期望服务能返回结果,那启动服务的客户端可以创建一个PendingIntent来获得一个广播broadcast(利用getBroadcast()),并把它放入启动服务的Intent并传到服务中去。然后服务就会用这个broadcast来传递结果。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
开发步骤:
- 定义一个继承Service的子类
- 在androidmanifest.xml中配置该Service
<strong>定义Service子类</strong>
<span style="white-space:pre"> </span>public class MyService extends Service {
public IBinder onBind(Intent arg0) //使用bindService绑定时才会被调用
{
return new MyBinder();
}
public class MyBinder extends Binder{ //使用bindService绑定时才用到
public void getXXX(){
return XXX;
}
}
}
3. 绑定Service(直接启动此处不再示范)
; <strong> Activity中获取Binder实例</strong>
<span style="white-space:pre"> </span> private <span style="color:#ff0000;background-color: rgb(255, 255, 0);">ServiceConnection</span> connection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(getApplicationContext(), "disconnected", Toast.LENGTH_SHORT).show();
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
binder = (MyBinder) service;
}
};
IntentService(新线程)
如果服务不需要同时处理多个请求的话,这是最佳的选择。 所有你要做的工作就是实现onHandleIntent()即可,它会接收每个启动请求的intent,然后就可在后台完成工作。因为大多数started服务都不需要同时处理多个请求(这实际上是一个危险的多线程情况),所以最佳方式也许就是用IntentService类来实现你的服务。
IntentService将执行以下步骤:
创建一个缺省的工作(worker)线程,它独立于应用程序主线程来执行所有发送到onStartCommand()的intent。
创建一个工作队列,每次向你的onHandleIntent()传入一个intent,这样你就永远不必担心多线程问题了。
在处理完所有的启动请求后,终止服务,因此你就永远不需调用stopSelf()了。
提供缺省的onBind()实现代码,它返回null。
提供缺省的onStartCommand()实现代码,它把intent送入工作队列,稍后会再传给你的onHandleIntent()实现代码。
以上所有步骤将汇成一个结果:你要做的全部工作就是实现onHandleIntent()的代码,来完成客户端提交的任务。(当然你还需要为服务提供一小段 构造方法。)
继承IntentService基类
已实现onBind() onStartCommand()方法,只需重写新线程要执行的方法:
<span style="white-space:pre"> </span>@Override
protected void onHandleIntent(Intent intent) {
System.out.println("started");
System.out.println("finished");
synchronized (this) {<span style="white-space:pre"> </span>//加锁 暂停线程
try {
wait(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/** * 构造方法是必需的,必须用工作线程名称作为参数 * 调用父类的[http://developer.android.com/reference/android/app/IntentService.html#IntentService(java.lang.String) IntentService(String)]构造方法。 */ public HelloIntentService() { super("HelloIntentService"); }
除了onHandleIntent()以外,唯一不需要调用父类实现代码的方法是onBind()(不过如果你的服务允许绑定,你还是需要实现它)。
请注意onStartCommand()方法必须返回一个整数。这个整数是描述系统在杀死服务之后应该如何继续运行(上一节中缺省的 IntentService 实现代码会替你处理这一点,当然那样你就无法修改这个处理过程)。onStartCommand()的返回值必须是以下常量之一:
-
START_NOT_STICKY
- 如果系统在 onStartCommand()返回后杀死了服务,则不会重建服务了,除非还存在未发送的intent。 当服务不再是必需的,并且应用程序能够简单地重启那些未完成的工作时,这是避免服务运行的最安全的选项。
-
START_STICKY
- 如果系统在 onStartCommand()返回后杀死了服务,则将重建服务并调用 onStartCommand(),但不会再次送入上一个intent, 而是用null intent来调用 onStartCommand() 。除非还有启动服务的intent未发送完,那么这些剩下的intent会继续发送。 这适用于媒体播放器(或类似服务),它们不执行命令,但需要一直运行并随时待命。
-
START_REDELIVER_INTENT
- 如果系统在 onStartCommand()返回后杀死了服务,则将重建服务并用上一个已送过的intent调用 onStartCommand()。任何未发送完的intent也都会依次送入。这适用于那些需要立即恢复工作的 活跃服务,比如下载文件。
关于这些返回值的详情,请参阅每个常量的参考文档链接。
//来自Android开发者
----------------------------------------------------------------------------------------------------------------------------
AIDL Service------跨进程通信
一.定义一个远程调用接口(相当于定义一个自定义的 IBinder);
二.为该接口提供一个实现类(相当于IBinder的实现类)
绑定本地/远程Service的区别:
- 本地 -- onBind()直接返回IBinder对象本身;
- 远程 -- onBind()返回IBinder对象的代理
interface MyAidl
{
int get();
}
继承stub(实现类IBinder MyAIidle接口,adt自动生成)
public class MyBinder extends Stub{
@Override
public int get() throws RemoteException {
// TODO Auto-generated method stub
return 0;
}
}