Android系列之Service:建立一个Bound Service

       最近在研究Android写一个学习笔记:

       一个BoundService 相当于C/S模式下的服务器,可以接受其他组件(如Activity)的连接,然后可以发请求,接受回复

创建一个BoundService,首先需要提供一个IBinder来实现C/S的通信,有三种方式来实现一个IBinder:
  1. 继承Binder类
  2. 使用Messager
  3. 使用AIDL(Android Interface Definition Language)
在Service里创建一个Binder的对象,该对象内容必须包含以下三点:
1.该对象包含可以被客户端调用的公共方法;
2.该对象要返回一个当前service的实例,以便客户端可以调用上面的方法;
3.在onBinder()方法里返回Binder对象

在客户端的onServiceConnected()方法里,客户通过对上面第二步返回的Service里方法的调用,实现通信。

Activity代码需要通过ServiceConnection(接口)的内部类实现来连接Service和Activity。
使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止。
Context.BIND_AUTO_CREATE:常量的作用,只要binding存在,就自动建立服务

使用使用bindService()启动Service会经历:
bindService()--onCreate() -- onBind() -- Service running-- onUnbind() -- onDestroy()

onBind将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service运行的状态或其他操作。把调用者(Context,例如Activity)和Service绑定在一起,Context退出了,Service就会调用onUnbind -- onDestroy相应退出,所以调用bindService的生命周期为:
onCreate() -- onBind(只一次,不可多次绑定) -- onUnbind() -- onDestory()

本地服务和Activity交互的示例:
如果activity和service之间需要传递参数或者方法调用,需要使用bind和unbind方法,这时activity和service是绑定在一起的。

以下是效果图,后台服务开启一个线程,每秒不断加一计数,前台Activity点第一个按钮绑定Service:

package org.newboy.activity;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

/*
 * 计数的服务
 */
public class CountService extends Service {

	private int count = 0;		//从0开始
	private boolean threadDisabled = false;		//判断线程是否可用

	@Override
	public IBinder onBind(Intent intent) {
		Log.i("tag", "onBind方法");
		//3.在onBinder()方法里返回Binder对象
		return new CountBinder();
	}
	
	//继承于Binder类
	public class CountBinder extends Binder {
		//1. 包含可供客户端调用的公共方法
		public CountService getCountService() {
			//2.返回当前Service的实例
			return CountService.this;
		}
	}
	
	@Override
	public void onCreate() {
		super.onCreate();
		Log.i("tag", "运行onCreate");
		new Thread(new Runnable() {
			@Override
			public void run() {
				while (!threadDisabled) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					count++;
					Log.i("tag", "count is " + count);
				}
			}
		}).start();
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		this.threadDisabled = true;
		Log.i("tag", "onDestroy");
	}

	/**
	 * 外面的应用得到此count的值
	 * @return
	 */
	public int getCount() {
		return count;
	}

}
package org.newboy.activity;

import org.newboy.activity.CountService.CountBinder;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

/*
 * 本地绑定的服务实例
 */
public class MainActivity extends Activity {

	private TextView txtShow;		//显示信息文本框
	private Button buttonStart;		//服务开始按钮
	private Button buttonShow;		//显示后台服务的值
	private Button buttonStop;		//服务停止

	private CountService countService; // 服务对象

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		txtShow = (TextView) findViewById(R.id.txtShow);		
		buttonStart = (Button) findViewById(R.id.buttonStart);
		buttonShow = (Button) findViewById(R.id.buttonShow);
		buttonStop = (Button) findViewById(R.id.buttonStop);

		buttonStart.setOnClickListener(listener);
		buttonShow.setOnClickListener(listener);
		buttonStop.setOnClickListener(listener);
	}

	// 服务连接以后的事件
	private ServiceConnection conn = new ServiceConnection() {
		@Override
		public void onServiceDisconnected(ComponentName name) {
			//服务停止的事件
		}

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// IBinder服务对象
			CountBinder binder = (CountBinder) service;
			countService = binder.getCountService();
		}
	};

	private View.OnClickListener listener = new View.OnClickListener() {
		@Override
		public void onClick(View v) {
			switch (v.getId()) {
				case R.id.buttonStart:
					// 开始后台的服务
					Intent service = new Intent(MainActivity.this, CountService.class);
					// 建立服务
					bindService(service, conn, Context.BIND_AUTO_CREATE);
					Toast.makeText(MainActivity.this, "服务连接", Toast.LENGTH_SHORT).show();
					break;
				case R.id.buttonShow:
					// 调用后台服务的方法
					int count = countService.getCount();
					txtShow.setText("当前的计数是:" + count);
					break;
				case R.id.buttonStop:
					// 停止服务
					unbindService(conn);
					Toast.makeText(MainActivity.this, "服务断开", Toast.LENGTH_SHORT).show();
					break;
				default:
					break;
			}

		}
	};
}
以下是配置文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
	package="org.newboy.activity" android:versionCode="1"
	android:versionName="1.0">
	<uses-sdk android:minSdkVersion="8" />

	<application android:icon="@drawable/icon" android:label="后台服务绑定演示">
		<activity android:name="org.newboy.activity.MainActivity"
			android:label="后台服务绑定演示">
			<intent-filter>
				<action android:name="android.intent.action.MAIN" />
				<category android:name="android.intent.category.LAUNCHER" />
			</intent-filter>
		</activity>
		<!-- 后台服务类 -->
		<service android:name="org.newboy.activity.CountService" />
	</application>
</manifest>

界面文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<TextView android:layout_width="fill_parent" android:id="@+id/txtShow"
		android:gravity="center_horizontal" android:textSize="22sp"
		android:layout_height="wrap_content" android:text="得到服务的值"
		android:layout_marginTop="5dip" android:layout_marginBottom="5dip" />
	<LinearLayout android:orientation="horizontal"
		android:layout_width="fill_parent" android:layout_height="wrap_content">
		<Button android:text="开始" android:id="@+id/buttonStart"
			android:layout_weight="1" android:layout_width="wrap_content"
			android:layout_height="wrap_content"></Button>
		<Button android:text="显示" android:id="@+id/buttonShow"
			android:layout_weight="1" android:layout_width="wrap_content"
			android:layout_height="wrap_content"></Button>
		<Button android:text="停止" android:id="@+id/buttonStop"
			android:layout_weight="1" android:layout_width="wrap_content"
			android:layout_height="wrap_content"></Button>
	</LinearLayout>
</LinearLayout>




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值