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;
- @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;

浙公网安备 33010602011771号