Android Service实现双向通信(一)
首先,大概来总结一下与Service的通信方式有很多种:
- 通过
BroadCastReceiver
:这种方式是最简单的,只能用来交换简单的数据; - 通过
Messager
:这种方式是通过一个传递一个Messager给对方,通过这个它来发送Message
对象。这种方式只能单向传递数据。可以是Service
到Activity
,也可以是从Activity
发送数据给Service
。一个Messeger不能同时双向发送; - 通过Binder来实现远程调用(IPC):这种方式是Android的最大特色之一,让你调用远程
Service
的接口,就像调用本地对象一样,实现非常灵活,写起来也相对复杂。
本文最重点谈一下怎么使用AIDL实现Service端和Client端的双向通信(或者叫"调用")。
首先定义一个AIDL接口如下:
// IRemoteService.aidl
package com.race604.servicelib;
interface IRemoteService {
int someOperate(int a, int b);
}
这里只定义了一个简单的接口someOperate()
,输入参数a
和b
,返回一个int
值。
Service的实现如下:
// RemoteService.java
package com.race604.remoteservice;
import ...
public class RemoteService extends Service {
private static final String TAG = RemoteService.class.getSimpleName();
private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
@Override
public int someOperate(int a, int b) throws RemoteException {
Log.d(TAG, "called RemoteService someOperate()");
return a + b;
}
};
@Override
public IBinder onBind(Intent intent) {
return mBinder; // 注意这里返回binder
}
}
这里,在RemoteService
里面实现一个IRemoteService.Stub
接口的Binder
,并且在onBind()中返回此Binder
对象。 在AndroidManifest.xml
对RemoteService
的申明如下:
<service
android:name=".RemoteService"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="com.race604.servicelib.IRemoteService" />
</intent-filter>
</service>
这里android:exported="true"
表示可以让其他进程绑定,这里还有一个<action android:name="com.race604.servicelib.IRemoteService" />
,这里是为了让后面的Client
通过此Action来绑定。
Client的调用方法如下:
package com.race604.client;
import ...
public class MainActivity extends ActionBarActivity implements View.OnClickListener {
private static final String TAG = MainActivity.class.getSimpleName();
private IRemoteService mService;
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Toast.makeText(MainActivity.this, "Service connected", Toast.LENGTH_SHORT).show();
mService = IRemoteService.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(MainActivity.this, "Service disconnected", Toast.LENGTH_SHORT).show();
mService = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.bind).setOnClickListener(this);
findViewById(R.id.unbind).setOnClickListener(this);
findViewById(R.id.call).setOnClickListener(this);
}
private void callRemote() {
if (mService != null) {
try {
int result = mService.someOperate(1, 2);
Toast.makeText(this, "Remote call return: " + result, Toast.LENGTH_SHORT).show();
} catch (RemoteException e) {
e.printStackTrace();
Toast.makeText(this, "Remote call error!", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(this, "Service is not available yet!", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bind:
Intent intent = new Intent(IRemoteService.class.getName());
bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
break;
case R.id.unbind:
unbindService(mServiceConnection);
break;
case R.id.call:
callRemote();
break;
}
}
}
在客户端,使用Context.bindService()函数,绑定到远程的Service。注意到这里的Intent intent = new Intent(IRemoteService.class.getName());
,和上面的Service申明的Action一致。BIND_AUTO_CREATE
这个Flag从名字就能看出,表示如果Bind的时候,如果还没有Service的实例,就自动创建。
这里有一个地方需要注意,在Android 5.0以后,就不允许使用非特定的Intent来绑定Service了,需要使用如下方法:
Intent intent = new Intent(IRemoteService.class.getName());
intent.setClassName("com.race604.remoteservice", "com.race604.remoteservice.RemoteService");
// 或者setPackage()
// intent.setPackage("com.race604.remoteservice");
bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
到这里就基本实现了一个完整的Client调用远程Service的实例了。
源代码可以参考这个Commit。
Android Service实现双向通信(一)的更多相关文章
- android service两种启动方式
android service的启动方式有以下两种: 1.Context.startService()方式启动,生命周期如下所示,启动时,startService->onCreate()-> ...
- 1、Android Studio集成极光推送(Jpush) 报错 java.lang.UnsatisfiedLinkError: cn.jpush.android.service.PushProtoco
Android studio 集成极光推送(Jpush) (华为手机)报错, E/JPush: [JPushGlobal] Get sdk version fail![获取sdk版本失败!] W/Sy ...
- Android Service完全解析,关于服务你所需知道的一切(下)
转载请注册出处:http://blog.csdn.net/guolin_blog/article/details/9797169 在上一篇文章中,我们学习了Android Service相关的许多重要 ...
- Android Service完全解析,关于服务你所需知道的一切(上)
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11952435 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的A ...
- android service 的各种用法(IPC、AIDL)
http://my.oschina.net/mopidick/blog/132325 最近在学android service,感觉终于把service的各种使用场景和用到的技术整理得比较明白了,受益颇 ...
- Android service介绍和启动方式
1.Android service的作用: service通常是用来处理一些耗时操作,或后台执行不提供用户交互界面的操作,例如:下载.播放音乐. 2.Android service的生命周期: ser ...
- Android Service初始
一.Service概念 1.Service是一个应用程序组件 2.Service没有图像化界面 3.Service通常用来处理一些耗时比较长的操作 4.可以使用Service更新ContentProv ...
- Android Service与Thread的区别
Android Service,后台,Android的后台就是指,它的运行是完全不依赖UI的.即使Activity被销毁,或者程序被关闭,只要进程还在,Service就可以继续运行.比如说一些应用程序 ...
- Android service binder aidl 关系
/********************************************************************************** * Android servic ...
随机推荐
- Python之log的处理方式
配置文件: #! /usr/bin/env python # -*- coding: utf-8 -*- """ logging配置 """ ...
- day19-IO多路复用
1.I/O多路复用指:通过一种机制,可监听多个描述符(soket对象)(文件句柄),一旦某个描述符发送编号(一般指读就绪或写就绪),能够通知程序进行相应的读写操作. 2.I/O多路复用方式:selec ...
- AngularJS自定义指令directive:scope属性 (转载)
原文地址:http://blog.csdn.net/VitaLemon__/article/details/52213103 一.介绍: 在AngularJS中,除了内置指令如ng-click等,我们 ...
- python之路 --- python文件模式
文件模式: 打开文件的模式有: r,只读模式(默认). w,只写模式.[不可读:不存在则创建:存在则删除内容:] a,追加模式.[可读: 不存在则创建:存在则只追加内容:] "+&quo ...
- css图像处理与动画
先讨论几个css 问题 1,css 清除浮动的方法 2,css 居中 3,多行省略号 4,小布局技巧 2D 动画功能属性兼容性:transform.transition.animation trans ...
- iOS学习笔记39-ReactiveCocoa入门
FRP,全称为Functional Reactive Programming,是一种响应变化的编程范式,最近几年比较火,大概的理解就像这样: 当a的值或者b的值发生变化时,c的值会自动响应a的值或b的 ...
- 前端CSS规范大全(转)
一.文件规范 1.文件均归档至约定的目录中. 具体要求通过豆瓣的CSS规范进行讲解: 所有的CSS分为两大类:通用类和业务类.通用的CSS文件,放在如下目录中: 基本样式库 /css/core 通用U ...
- debug模式总是自动跳到ThreadPoolExecutor
debug模式下eclipse总是自动跳到ThreadPoolExecutor解决方案 debug模式下eclipse总是自动跳到ThreadPoolExecutor解决方案 在eclipse中点击W ...
- [POI2007]MEG-Megalopolis (树状数组,Dfs序)
题目描述 Solution 这道题考试的时候竟然没有仔细想,结果只拿了暴力分... 其实就是一个 DFS序+树状数组. 我们先把用 DFS 把它变成一个序列,同时记录它们的 \(siz\). 那么我们 ...
- iOS-ARC机制
内存管理是开发软件中重要的一个课题.如果内存管理不当,轻者内存泄露,重者程序崩溃. 下面重要讲述一下iOS的ARC(Automatic Reference Counting))机制. ARC的历史由来 ...