[翻译]API Guides - Bound Services
官方文档原文地址:http://developer.android.com/guide/components/bound-services.html
一个Bound Service是一个客户端-服务器接口的服务。一个Bound Service允许组件(像activity)绑定一个service,发送请求,接受结果,甚至进行进程间通信。一个Bound Service通常只在他向其它组件提供服务的时候运行,不会无法确定的运行在后台的。
publicclassLocalServiceextendsService{
// Binder given to clients
privatefinalIBinder mBinder =newLocalBinder();
// Random number generator
privatefinalRandom mGenerator =newRandom(); /**
* Class used for the client Binder. Because we know this service always
* runs in the same process as its clients, we don't need to deal with IPC.
*/
publicclassLocalBinderextendsBinder{
LocalService getService(){
// Return this instance of LocalService so clients can call public methods
returnLocalService.this;
}
} @Override
publicIBinder onBind(Intent intent){
return mBinder;
} /** method for clients */
publicint getRandomNumber(){
return mGenerator.nextInt(100);
}
}
publicclassBindingActivityextendsActivity{
LocalService mService;
boolean mBound =false; @Override
protectedvoid onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
} @Override
protectedvoid onStart(){
super.onStart();
// Bind to LocalService
Intent intent =newIntent(this,LocalService.class);
bindService(intent, mConnection,Context.BIND_AUTO_CREATE);
} @Override
protectedvoid onStop(){
super.onStop();
// Unbind from the service
if(mBound){
unbindService(mConnection);
mBound =false;
}
} /** Called when a button is clicked (the button in the layout file attaches to
* this method with the android:onClick attribute) */
publicvoid onButtonClick(View v){
if(mBound){
// Call a method from the LocalService.
// However, if this call were something that might hang, then this request should
// occur in a separate thread to avoid slowing down the activity performance.
int num = mService.getRandomNumber();
Toast.makeText(this,"number: "+ num,Toast.LENGTH_SHORT).show();
}
} /** Defines callbacks for service binding, passed to bindService() */
privateServiceConnection mConnection =newServiceConnection(){ @Override
publicvoid onServiceConnected(ComponentName className,
IBinder service){
// We've bound to LocalService, cast the IBinder and get LocalService instance
LocalBinder binder =(LocalBinder) service;
mService = binder.getService();
mBound =true;
} @Override
publicvoid onServiceDisconnected(ComponentName arg0){
mBound =false;
}
};
}
- service实现一个Handler为从客户端的每一个调用接收回调。
- Hander用来创建Messenger对象。
- Messenger创建IBinder对象,用于客户端从service的onBind()方法了获取IBinder。
- 客户端使用IBinder来初始化Messenger,这样客户端可以使用它给service发送Message对象。
- service从它的handle里接收每一个Message,准确的说,是在handleMessage()方法里。
在这种方式里,没有任何在service里的方法给客户端调用。取而代之的是,客户端发送消息给service的handler获取。
publicclassMessengerServiceextendsService{
/** Command to the service to display a message */
staticfinalint MSG_SAY_HELLO =1; /**
* Handler of incoming messages from clients.
*/
classIncomingHandlerextendsHandler{
@Override
publicvoid handleMessage(Message msg){
switch(msg.what){
case MSG_SAY_HELLO:
Toast.makeText(getApplicationContext(),"hello!",Toast.LENGTH_SHORT).show();
break;
default:
super.handleMessage(msg);
}
}
} /**
* Target we publish for clients to send messages to IncomingHandler.
*/
finalMessenger mMessenger =newMessenger(newIncomingHandler()); /**
* When binding to the service, we return an interface to our messenger
* for sending messages to the service.
*/
@Override
publicIBinder onBind(Intent intent){
Toast.makeText(getApplicationContext(),"binding",Toast.LENGTH_SHORT).show();
return mMessenger.getBinder();
}
}
publicclassActivityMessengerextendsActivity{
/** Messenger for communicating with the service. */
Messenger mService =null; /** Flag indicating whether we have called bind on the service. */
boolean mBound; /**
* Class for interacting with the main interface of the service.
*/
privateServiceConnection mConnection =newServiceConnection(){
publicvoid onServiceConnected(ComponentName className,IBinder service){
// This is called when the connection with the service has been
// established, giving us the object we can use to
// interact with the service. We are communicating with the
// service using a Messenger, so here we get a client-side
// representation of that from the raw IBinder object.
mService =newMessenger(service);
mBound =true;
} publicvoid onServiceDisconnected(ComponentName className){
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
mService =null;
mBound =false;
}
}; publicvoid sayHello(View v){
if(!mBound)return;
// Create and send a message to the service, using a supported 'what' value
Message msg =Message.obtain(null,MessengerService.MSG_SAY_HELLO,0,0);
try{
mService.send(msg);
}catch(RemoteException e){
e.printStackTrace();
}
} @Override
protectedvoid onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
} @Override
protectedvoid onStart(){
super.onStart();
// Bind to the service
bindService(newIntent(this,MessengerService.class), mConnection,
Context.BIND_AUTO_CREATE);
} @Override
protectedvoid onStop(){
super.onStop();
// Unbind from the service
if(mBound){
unbindService(mConnection);
mBound =false;
}
}
}
LocalService mService;
privateServiceConnection mConnection =newServiceConnection(){
// Called when the connection with the service is established
publicvoid onServiceConnected(ComponentName className,IBinder service){
// Because we have bound to an explicit
// service that is running in our own process, we can
// cast its IBinder to a concrete class and directly access it.
LocalBinder binder =(LocalBinder) service;
mService = binder.getService();
mBound =true;
} // Called when the connection with the service disconnects unexpectedly
publicvoid onServiceDisconnected(ComponentName className){
Log.e(TAG,"onServiceDisconnected");
mBound =false;
}
};
Intent intent =newIntent(this,LocalService.class);
bindService(intent, mConnection,Context.BIND_AUTO_CREATE);
- bindService()的第一个参数是一个指定了绑定哪一个service的Intent对象(虽然intent也可以是隐式的)。
- 第二个参数是ServiceConnection对象。
- 第三个参数是一个绑定可选的标示符。通常为了去创建一个不存在的service,应该使用BIND_AUTO_CREATE。其它的值是BIND_DEBUG_UNBIND和BIND_NOT_FOREGROUND,或者0。
- 你应该总是捕获DeadObjectException异常,这个异常将在连接被破坏的时候抛出,也是唯一一个通过远程方法抛出的异常。
- 在进程之间,对象的引用被计数。( Objects are reference counted across processes)
- 你应该总是在你客户端的生命周期里成对的去绑定和解绑,匹配与连接与断开的时候。
- 如果你仅仅是希望service与你的activity交互在可见的时候,你应该在onStart()方法中绑定,onStop()方法中解绑。
- 如果你希望你的activity能够在自己停止前一直能接收到反馈结果,你应该在onCreate()里绑定,在onDestroy()里解绑。注意,这意味着你的activity需要一直使用service(甚至是在后台。)所以,如果service在另一个进程里,所以你应该提高你进程的权重,这样系统就不太可能会杀掉它了。


[翻译]API Guides - Bound Services的更多相关文章
- [翻译]API Guides - Layouts
官方文档地址:http://developer.android.com/guide/topics/ui/declaring-layout.html PS:API Guides里面的内容不免都简单些,翻 ...
- [翻译]API Guides - Service
官方文档原文地址:http://developer.android.com/guide/components/services.html Service是应用程序组件之一,它并不提供一个用户界面,可以 ...
- Android API Guides 学习笔记---Application Fundamentals(一)
今天开始学习google官网上的API guides ,主要读了Application Fundamentals这一章节,此章节介绍了一个App的基本组成,共包括四大部分内容. 1. App ...
- Android开发-API指南-Bound 类型的服务
Bound Services 英文原文:http://developer.android.com/guide/components/bound-services.html 采集(更新)日期:2014- ...
- ASP.NET实现二维码 ASP.Net上传文件 SQL基础语法 C# 动态创建数据库三(MySQL) Net Core 实现谷歌翻译ApI 免费版 C#发布和调试WebService ajax调用WebService实现数据库操作 C# 实体类转json数据过滤掉字段为null的字段
ASP.NET实现二维码 using System;using System.Collections.Generic;using System.Drawing;using System.Linq;us ...
- C# 调用百度翻译Api
这是简单的界面.用的是wpf,winform也可以 具体的操作类 public partial class MainWindow : Window { string url = "" ...
- 基于百度翻译API开发属于自己的翻译工具
你是否每天使用着网页翻译工具?你是否遇到过这种情况,上网过程中遇到一个很长的单词但是又不能复制,要开两个浏览器,一个打开百度翻译,照着另一个网页输入单词?你安装了各种翻译软件后,又删除,只因忍受不了那 ...
- Python 调用百度翻译API
由于实习公司这边做的是日文app,有时要看看用户反馈,对于我这种五十音图都没记住的人,表示百度翻译确实还可以.但不想每次都复制粘贴啊,google被墙也是挺蛋疼的事,所以用python结合baidu ...
- [Python] 使用有道翻译API
Python 使用youdao (有道翻译)API 想写一个给自己记录背单词状况的软件,需要获取英文单词的中文释义(基本功能).考虑使用有道翻译的API实现获取英文单词的中文释义的方法. 获取API_ ...
随机推荐
- leetcode记录-回文数
判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 示例 1: 输入: 121 输出: true 示例 2: 输入: -121 输出: false 解释: 从左向 ...
- 20155229实验二 《Java面向对象程序设计》实验报告
20155229实验二 <Java面向对象程序设计>实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 ...
- 2016-2017-20155329 《Java程序设计》第十周学习总结
学号 2016-2017-20155329 <Java程序设计>第十周学习总结 教材学习内容总结 学习目标 了解计算机网络基础 OSI分层(7层):物理层.数据链路层.网络层.传输层.会话 ...
- 20155336 实验三 敏捷开发与XP实践
20155336 实验三 敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 实验内容及步骤 (一)编码标准:在IDEA中使用工具(Code->Reformate Code)把代码重 ...
- ASCII, UNICODE, UTF-8, 字符集理解
字符编码的发展历史 一个字节:最初一个字节的标准是混乱的,出现过4位.6位.7位的一字节标准,最终由于历史原因和物理存储需求(8位是2的3次方,方便物理存储),所以采用了8位为一个字节的标准. ASC ...
- 2288: 【POJ Challenge】生日礼物
2288: [POJ Challenge]生日礼物 https://lydsy.com/JudgeOnline/problem.php?id=2288 分析: 贪心+堆+链表. 首先把序列变一下,把相 ...
- JS基础,课堂作业,相亲问答
相亲问答 <script> var a = prompt("你有房子么?"); var b = prompt("你有钱么?"); var c = p ...
- 180724-统计JVM进程中线程数两种方式小记
I. 统计进程中的线程数 相关系列博文推荐: 180711-JVM定位分析CPU性能消耗 180704-JDK常用监控参数 jvm调优的工具介绍 1. proc查询 /proc 目录以可读文本文件形式 ...
- selenium 各种很奇葩的异常
问题1:使用selenium3+java的脚本模拟登陆时,总是提示用户名,密码错误 解决方法:1 在执行输入用户名和密码的代码之前,加上driver.navigate().refresh(); QQ群 ...
- Docker虚拟机172.17网段冲突,导致网络访问问题
在虚拟机中安装docker,linux ubuntu16 ,安装完公司172.17网段被docker0覆盖,导致ssh无法连接到ubuntu. 经过官网的这篇build your own bridge ...