service怎么得到绑定的activity实例

activity可以操作service了,我们还需要service能操作activity。
我觉得可以有3中方式:
1.直接把activity传给service,service通过activity实例随便操作activity
2.使用接口回调方式,activity实现相应的接口,service通过接口进行回调,比较灵活
3.使用广播

使用广播是比较常见的方式,我们就不具体讲解了,下面我们介绍前面2中方法,具体看代码,用service更新seekbar。
我们的activity代码:
[html] view plain copy
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代码:
[html] view plain copy
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的。

接口:
[html] view plain copy
package com.hck.bindservice;

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

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

上面是使用 bindService来启动service的,那么如果我们使用startService启动service时候,上面的办法就不行了。
因为onBind不会执行,我们获取不到IBinder实例。这个时候,我们可以使用设计模式的观察者模式来处理。
posted @ 2016-11-18 18:10  天涯海角路  阅读(100)  评论(0)    收藏  举报