[翻译]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_ ...
随机推荐
- 我的职业规划(android)
通过一段时间的想法,自己大概圈定了自己的未来三年的职业规划,关于android的,希望大家多多批评,多多指教.或者大家也能讨论下自己对于未来的期许或者路线,虽然每个人都有自己自身的情况,但是总会有一些 ...
- ubuntu下python在pycharm环境下安装setuptools和pip,和distutils.core
python安装好后,我们用pycharm安装所需的第三方模块时,出现“Python packaging tools not found. install packaging tools”点击安装输完 ...
- 随笔三 安装Linux操作系统
一.虚拟机安装Ubuntu图文教程]在自己笔记本上安装Linux操作系统 我参考了VirtualBox虚拟机安装Ubuntu的图文教程,根据图片和所附内容一步步的将虚拟机安装到位,没看安装教程之前完全 ...
- 20155320 2016-2017-2《Java程序设计》课程总结
20155320 2016-2017-2<Java程序设计>课程总结 (按顺序)每周作业链接汇总 预备作业1:第一次写随笔,回答了老师的一些问题,写下了期望和目标 预备作业2:总结了一下自 ...
- JDK核心源码
一.核心包有哪些? Jdk的包中,除开了lang包下面的类,用得最多的应该要属于util包下面的类了, 本篇文章主要针对Jdk的util包下面的类(util目录下面的类,暂时不包括util 包下面的子 ...
- cogs696 longest prefix
cogs696 longest prefix 原题链接 IOI1996原题? 其实这题我不会. map+string+手动氧气大法好 //就是这么皮(滑稽 Code // It is made by ...
- cookie和session在Django中的应用
1 会话跟踪技术 什么是会话跟踪 我们需要先了解一下什么是会话!可以把会话理解为客户端与服务器之间的一次会晤,在一次会晤中可能会包含多次请求和响应.例如你给10086打个电话,你就是客户端,而1008 ...
- LUA对象
Rectangle = {width = , height = , area = }; function Rectangle:new(o, width, height) o = o or {}; se ...
- java 多路分发
1.概念 一个函数处理多种类型,其实和多态差不多. 但是要处理两种或者多种类型的数据时,就需要判断每种类型以及每种类型所对应的处理.(PS:我只是在走别人的老路,网上一搜这种概念,博客一大堆,我不知道 ...
- youtube视频下载和搬运的方法
youtube全球最大的视频网站, 全世界每天有三分之一的网民在youtube上观看视频, 可是大部分人不知道, 在这些网民有一小部分人是依靠youtube生存的, 他们上传视频到youtube, y ...