在上一篇中介绍了Service与Activity的区别及Service两种启动方式中的第一种启动方式startService().

我们会发现用startService()、stopService()方法启动和关闭一个Service时,Service与访问者之间基本上不存在太多的关联,因此Service和访问者之间也无法进行通信和数据交换。如果要实现Service与Activity之间的通信就要使用第二种启动方式(绑定启动)bindService()启动、unbindService()关闭。

下面我们来看一下bindService方法的各个参数的含义:(下图是API中关于该方法的说明)

官方说明地址:http://developer.android.com/reference/android/content/Context.html#bindService(android.content.Intent, android.content.ServiceConnection, int)

各个参数的大致含义如下:

service:通过Intent指定要启动的Service.

conn:该参数是一个ServiceConnection对象,该对象用于监听访问者与Service对象的onServiceConnected(ComponentName name, IBinder service)方法:当Service所在的宿主进程由于异常终止或者由其他原因终止,导致该Service与访问者之间断开连接时回调该ServiceConnection对象的onServiceDisconnected(ComponentName name)方法。

	private ServiceConnection conn = new ServiceConnection() {

		@Override
public void onServiceDisconnected(ComponentName name) {
System.out.println("--Service Disconnected--");
} @Override
public void onServiceConnected(ComponentName name, IBinder service) {
System.out.println("--Service Connected--");
binder = (MyBinder) service;
}
};

flags:指定绑定时是否自动创建Service.该参数为0则不自动创建,为BIND_AUTO_CREATE(自动创建)

注意:当调用者主动通过nubindService()方法断开与Service的连接时,ServiceConnection对象的onServiceDisconnected(ComponentName name)方法不会被调用。

可以看到上面onServiceConnected方法中有一个IBinder的参数对象,实际上Activity与Service之间的绑定是通过该参数进行绑定和通信的。这时候可能有的朋友就有点迷糊了,这到底是怎样实现通信的呢?

其实,当你在开发一个Service的时候Service类会强制你实现一个方法onBind(Intent intent).在绑定本地(没有跨越进程)Service的情况下,onBind(Intent intent)方法返回的IBinder对象将会传给上面介绍的bindService()方法参数ServiceConnection对象的o中的IBinder.这样访问者就可以通过操作该参数中IBinder对象来实现对Service中数据的读取。

在实际开发中通常会采用继承Binder(IBinder的实现类)的方式实现自己的IBinder对象。

下面我们来实现一个绑定的Service与Activity之间的通信:

(1)建立一个service返回Binder对象

package com.example.testservice;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder; public class BindService extends Service{ private int count;
private boolean quit;
//定义onBinder方法所返回的对象
private MyBinder binder = new MyBinder();
//通过继承Binder来实现IBinder类
public class MyBinder extends Binder{
public int getCount(){
return count;
}
} @Override
public IBinder onBind(Intent intent) {
System.out.println("Service is Binded");
return binder;
} @Override
public void onCreate() { super.onCreate();
System.out.println("Service is Created");
new Thread(){
public void run() {
while(!quit){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
count++;
}
};
}.start();
} @Override
public boolean onUnbind(Intent intent) {
System.out.println("Service is UnBinded");
return super.onUnbind(intent);
} @Override
public void onDestroy() {
super.onDestroy();
this.quit = true;
System.out.println("Service is Destroyed");
} }

(2)创建ServiceConnection接口实例对象,并将该对象的实例作为参数传给bindService()方法,通过调用ServiceConnection接口实例中的nServiceConnected方法的参数获得IBinder对象。

package com.example.testservice;

import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast; import com.example.testservice.BindService.MyBinder; public class BindServiceTest extends Activity{
Button bind, unbind, getServiceStatus; BindService.MyBinder binder; private ServiceConnection conn = new ServiceConnection() { @Override
public void onServiceDisconnected(ComponentName name) {
System.out.println("--Service Disconnected--");
} @Override
public void onServiceConnected(ComponentName name, IBinder service) {
System.out.println("--Service Connected--");
binder = (MyBinder) service;
}
}; protected void onCreate(android.os.Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); bind = (Button)findViewById(R.id.button1);
unbind = (Button) findViewById(R.id.button2);
getServiceStatus = (Button) findViewById(R.id.button3); final Intent intent = new Intent(); intent.setAction("com.meritit.service.BIND_SERVICE"); bind.setOnClickListener(new OnClickListener() { @Override
public void onClick(View arg0) {
bindService(intent, conn, Service.BIND_AUTO_CREATE);
}
}); unbind.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
unbindService(conn);
}
}); getServiceStatus.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
Toast.makeText(BindServiceTest.this, "Service的count值是:" + binder.getCount(),
Toast.LENGTH_SHORT).show();
}
});
};
}

通过该方法Activity可以非常方便的访问到Service的运行状态,这里的IBinder可以看成Service组件所返回的代理对象。

下一篇将介绍:Service的生命周期

Android菜鸟的成长笔记(18)——绑定本地Service并与之通信的更多相关文章

  1. Android菜鸟的成长笔记(16)——Service简介

    Service是Android四大组件之一 1.Service与Activity的区别在:Service一直在后台运行,没有用户界面. 2.选择Activity与Service的标准:如果某个程序组件 ...

  2. Android菜鸟的成长笔记(19)——Service的生命周期

    前面两篇文章介绍了关于Service的两种启动方式,简要总结如下: Context.startService() Context.bindService() 1. startService()的目的是 ...

  3. Android菜鸟的成长笔记(17)—— 再看Android中的Unbounded Service

    原文:Android菜鸟的成长笔记(17)-- 再看Android中的Unbounded Service 前面已经写过关于startService(Unbounded Service)的一篇文章:&l ...

  4. Android菜鸟的成长笔记(1)——Android开发环境搭建从入门到精通

    原文:Android菜鸟的成长笔记(1)--Android开发环境搭建从入门到精通 今天在博客中看到好多Android的初学者对Android的开发环境的搭建不熟悉而导致不能进行学习,所以我决定自己写 ...

  5. Android菜鸟的成长笔记(7)——什么是Activity

    原文:[置顶] Android菜鸟的成长笔记(7)——什么是Activity 前面我们做了一个小例子,在分析代码的时候我们提到了Activity,那么什么是Activity呢? Activity是An ...

  6. Android菜鸟的成长笔记(3)——给QQ登录界面说So Easy

    原文:Android菜鸟的成长笔记(3)--给QQ登录界面说So Easy 上一篇:Android菜鸟的成长笔记(2)--第一个Android应用 我们前面已经做了第一个Android应用程序,虽然有 ...

  7. Android菜鸟的成长笔记(2)——第一个Android应用

    原文:Android菜鸟的成长笔记(2)--第一个Android应用 上一篇:Android菜鸟的成长笔记(1)--Anddroid环境搭建从入门到精通 在上一篇Android菜鸟的成长笔记(1)中我 ...

  8. Android菜鸟的成长笔记(14)—— Android中的状态保存探究(上)

    原文:[置顶] Android菜鸟的成长笔记(14)—— Android中的状态保存探究(上) 我们在用手机的时候可能会发现,即使应用被放到后台再返回到前台数据依然保留(比如说我们正在玩游戏,突然电话 ...

  9. Android菜鸟的成长笔记(13)——异步任务(Async Task)

    原文:[置顶] Android菜鸟的成长笔记(13)——异步任务(Async Task) Android的UI线程主要负责处理用户的事件及图形显示,因此主线程UI不能阻塞,否则会弹出一个ANR(App ...

  10. Android菜鸟的成长笔记(12)——Handler、Loop、MessageQueue

    原文:[置顶] Android菜鸟的成长笔记(12)——Handler.Loop.MessageQueue 当一个程序第一次启动时,Android会启动一条主线程(Main Thread),主线程主要 ...

随机推荐

  1. 学习 Perl(一) —— 安装及 hello world

    所谓存在的即是合理的,尤其适用于琳琅满目的编程语言界.每种编程语言在设计之初均只为解决特定领域的特定问题而生,没有语言擅长所有的领域能够完美地解决所有的问题. 这里推荐一本经典的 perl 入门书:P ...

  2. μC/OS中的任务就绪表

    为了便于对就绪表的查找,μC/OSII又定义了一个数据类型为INT8U的变量OSRdyGrp, 并使该变量的每一位都对应OSRdyTbl[ ]的一个任务组(即数组的一个元素),如果某任务组中 有任务就 ...

  3. (转)高强度密码管理软件KeePass使用详解

    转自:http://www.ruancan.com/ 算下来,你接触电脑有多久了?从第一次上网,到今天,你一共申请了多少个网站或者软件的帐号?相信这是一个几乎无人能够回答的问题. 无数人面临着这两个问 ...

  4. [Angular 2] Share Template Content In Another Template With Content Projection <ng-content>

    Angular 1 provided a mechanism to place content from your template inside of another template called ...

  5. Win7长时间使用占用内存高问题记

    工作电脑Win7 64位,8G内存,没设置虚拟内存,连续运行几天,中间只是睡眠,今天在试用时总提示内存不足,看任务管理器已经把占用内存比较多的几个进程都结束掉了,但内存占用依旧是80%以上,eclip ...

  6. Java 开源博客——B3log Solo 0.6.7 正式版发布了!

    Java 开源博客 -- B3log Solo 0.6.7 正式版发布了!欢迎大家下载. 另外,欢迎观摩 B3log 团队的新项目:Wide,也非常欢迎大家参与进来 :-) 特性 基于标签的文章分类 ...

  7. 【u251】心灵的抚慰

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 病毒问题解决后,神牛们的心灵久久不能平静.他可以从一个程序联想到一些相似的程序.比如从程序1联想到2, ...

  8. [TypeStyle] Load raw CSS in TypeStyle

    TypeStyle tries to be an all in one CSS in JS management solution so you can always fall back to raw ...

  9. JavaWeb网站技术架构

    JavaWeb网站技术架构总结   题记 工作也有几多年了,无论是身边遇到的还是耳间闻到的,多多少少也积攒了自己的一些经验和思考,当然,博主并没有太多接触高大上的分布式架构实践,相对比较零碎,随时补充 ...

  10. 选择标识符(identifier)

    整数通常是标识列最好的选择,因为它们很快并且可以使用auto_increment:千万不要使用enum和set类型作为标识列:尽量避免使用字符串类型作为标识列,因为他们很消耗空间,并且通常比数字类型慢 ...