android activity和service的交互介绍

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;@Overrideprotected 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) { //绑定servicebindService(new Intent(this,MyService.class), connectionService, 1);}/** * * @author Administrator *实现service接口,用于service绑定时候,回调 */class ConnectionService implements ServiceConnection{@Overridepublic 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);//}//});}@Overridepublic 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);}@Overrideprotected 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;@Overridepublic IBinder onBind(Intent intent) {return new MyBuild();}@Overridepublic void onCreate() {super.onCreate();updateProgress=new UpdateProgress();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {return super.onStartCommand(intent, flags, startId);}/** * * @author Administrator * 线程用来改变seekbar进度的大小 * */class UpdateProgress implements Runnable{@Overridepublic 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实例。这个时候,我们可以使用设计模式的观察者模式来处理。

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

例子源码:

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







,生活中若没有朋友,就像生活中没有阳光一样

android activity和service的交互介绍

相关文章:

你感兴趣的文章:

标签云: