您的位置:首页 > 移动开发 > Android开发

android activity和service的交互介绍

2015-03-03 14:54 274 查看
android开发中,作为4大组件的service在开发中经常会使用到。很多时候,我们的activity和service之间需要进行相应的交互,activity需要调用service里面的方法实现某些功能,service需要调用activity的方法,实现界面更新等的交互。

实现2者之间相互交互的主要方式是:service中有个类部类继承Binder,然后提供一个公有方法,返回当前service的实例。 activity通过bindService来开启一个service,service通过onBind方法,返回一个IBinder实例(我们创建的那个类部类实例),activity中通过onServiceConnected方法,获取IBinder实例,然后再通过IBinder实例来获取service实例,这样,我们得到了service的实例,那么我们的activity就可以随心所欲的使用它里面的各种方法来操作它了。

上面activity可以操作service了,我们还需要service能操作activity。

我觉得可以有3中方式:

1.直接把activity传给service,service通过activity实例随便操作activity

2.使用接口回调方式,activity实现相应的接口,service通过接口进行回调,比较灵活

3.使用广播

使用广播是比较常见的方式,我们就不具体讲解了,下面我们介绍前面2中方法,具体看代码,用service更新seekbar。

我们的activity代码:

package com.hck.bindservice;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.SeekBar;
import android.widget.Toast;

import com.hck.bindservice.MyService.MyBuild;

public class MainActivity extends Activity {
private MyService myService;  //我们自己的service
private SeekBar pBar;  //模拟service更新进度条
private ConnectionService connectionService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
pBar = (SeekBar) findViewById(R.id.seekbar);
connectionService=new ConnectionService();
}

public void startService(View view) { //绑定service
bindService(new Intent(this,MyService.class), connectionService, 1);
}
/**
*
* @author Administrator
*实现service接口,用于service绑定时候,回调
*/
class ConnectionService  implements ServiceConnection
{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myService=((MyBuild)service).getMyService(); //获取Myservice对象

/**
* 直接把当前对象传给service,这样service就可以随心所欲的调用本activity的各种可用方法
*/
myService.setMainActivity(MainActivity.this); //把当前对象传递给myservice

/**
* 使用一个接口来实现回调,这样比上面方法更加灵活,推荐
*/
//			myService.setOnProgressBarListener(new UpdateProgressListener() {
//
//				@Override
//				public void updateBar(int size) {
//					updateBar(size);
//				}
//			});

}

@Override
public void onServiceDisconnected(ComponentName name) {

}
}
/**
*
* @param size
* 更新seekbar
*/
public void updateBar(int size)
{
pBar.setProgress(size);
}

/**
*
* @param view
* 开始更新seekbar
*/
public void startBar(View view) {
if (myService==null) {
Toast.makeText(this, "请先开始service", Toast.LENGTH_LONG).show();
}
else {
myService.startUpdateProgress();
}
}
/**
*
* @param view
* 停止更新seekbar
*/
public void stopBar(View view) {

if (myService==null) {
Toast.makeText(this, "更新没有开始", Toast.LENGTH_LONG).show();
}
else {
myService.stopUpdateProgress();
}
}
/**
*
* @param view
* 停止service
*/
public void stopService(View view) {
myService=null;
unbindService(connectionService);

}
@Override
protected void onDestroy() {
super.onDestroy();
try {
unbindService(connectionService);
} catch (Exception e) {
}

}

}


重要代码是onServiceConnected回调方法里面

myService=((MyBuild)service).getMyService(); //获取Myservice对象

获取service对象后,我们想怎么操作它都行了,比如上面的,把activity实例直接通过它的方法传递过去,便于

service调用activity的各种方法。或者,设置传递一个回调接口对象过去,用户回调

service代码:

package com.hck.bindservice;

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

public class MyService extends Service{
private int size=0;
private UpdateProgress updateProgress;
private final long TIME=2000;
private boolean isUpdate=true;
private MainActivity activity;
private UpdateProgressListener listener;
@Override
public IBinder onBind(Intent intent) {

return new MyBuild();
}
@Override
public void onCreate() {
super.onCreate();
updateProgress=new UpdateProgress();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
/**
*
* @author Administrator
* 线程用来改变seekbar进度的大小
*
*/
class UpdateProgress implements Runnable
{
@Override
public void run() {
if (isUpdate) {
size+=10;
if (size>100) {
size=0;
}
handler.sendEmptyMessage(0);
}
}
}
/**
* 调用更新相应方法,更新进度条
*/
Handler handler=new Handler()
{
public void handleMessage(android.os.Message msg) {
/**
* 直接调用activity对象里面的方法
*/
if (activity!=null) {
activity.updateBar(size);
}

/**
* 使用接口回调
*/
//			if (listener!=null) {
//				listener.updateBar(size);
//			}
handler.postDelayed(updateProgress, TIME);
};
};

/**
* 停止更新
*/
public void stopUpdateProgress()
{
isUpdate=false;
}
/**
* 开启更新
*/
public void startUpdateProgress()
{

if (!isUpdate) {
handler.post(updateProgress);
}
isUpdate=true;
}
public void onDestroy() {
isUpdate=false;
};

/**
*
* @param activity
* 初始化MainActivity对象
*/
public void setMainActivity(MainActivity activity)
{
this.activity=activity;
}
/**
*
* @param listener
* 初始化UpdateProgressListener对象
*/
public void setOnProgressBarListener(UpdateProgressListener listener)
{
this.listener=listener;
}

/**
*
* @author Administrator
* 使用类部类,返回当前service的实例,用于activity,调用service的各种方法
*
*/
class MyBuild extends Binder
{
public MyService getMyService()
{
return MyService.this;
}
}

}


service里面最重要的就是,最下面我们的MyBuild类部类了,通过它的getMyService方法,获取service的实例

该类的实例实在onBind时候,我们返回给activity的。

接口:

package com.hck.bindservice;

public interface UpdateProgressListener {
public void updateBar(int size);
}


一个简单接口,用于service回调activity

上面是使用 bindService来启动service的,那么如果我们使用startService启动service时候,上面的办法就不行了。

因为onBind不会执行,我们获取不到IBinder实例。这个时候,我们可以使用设计模式的观察者模式来处理。

其它不清楚,还有什么比较好的办法没有,我是没有想到,有知道的朋友,请告知,谢谢

例子源码:http://download.csdn.net/detail/hhhccckkk/8469069 

请把 private boolean isUpdate=true;    改为 private boolean isUpdate=false;






内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android service