Service和Activity之间的通信

原创 2015年11月21日 16:22:26

在Android中,Activity主要负责前台页面的展示,Service主要负责需要长期运行的任务,所以在我们实际开发中,就会通常遇到Activity与Service之间的通信,我们一般在Activity中启动后台Service,通过Intent来启动,Intent中我们可以传递数据给Service,但是我们Service执行某些操作之后想要更新UI线程,我们可以通过以下方法。

通过binder对象

当Activity通过调用 bindService(Intent service, ServiceConnection conn, int flags),我们可以在Activity中得到一个Ibinder的对象实例,可以在Ibinder中得到数据。
- 在Service的onBind(Intent intent)的方法中,返回一个自定义的Binder对象

class MusicBinder extends Binder {
        public int getProgress() { // 返回进度
                if (player.isPlaying()) {//这儿是音乐播放器在播放
                return player.getCurrentPosition();
            } else {
                return 0;
            }
        }
    }  
  • 在Activity中重写ServiceConnection中onServiceConnecte(ComponentName name, Ibinder service)就是上面定义的对象,可以强转,然后调用相应的方法
private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            binder = (MusicBinder) service;
            Log.i("MainActivity", "----"+binder.getProgress());
        }
    };  

通过Braodcast广播的形式

思路:当我们进度发生变化的时候我们发送一条广播,然后在Activity注册广播接收器,接收到广播之后更新ProgressBar
在Activity中定义并注册这个广播

class MyReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            int progress = intent.getIntExtra("progress", 0);
            pb_1.setProgress(progress);
            tv_1.setText(progress + "%");
        }
    }  

在Service中启动线程,不断发送广播

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        new Thread() {
            public void run() {
                Intent i1 = new Intent();
                i1.setAction("myrecevier");
                for (int i = 0; i < 101; i++) {
                    i1.putExtra("progress", i);
                    sendBroadcast(i1);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //此处应该发消息关闭
            };
        }.start();
        return super.onStartCommand(intent, flags, startId);
    }  

利用hanlder传递消息

  • 在activity中新建一个handler对象,重写handleMessage()方法,并定义一个可以得到当前Activity静态引用和handler对象的引用,然后在广播中得到这个handler用来发送消息。
private Handler handler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
            case 1:
                tv_2.setText("" + msg.arg1);
                break;
            }
        };
    };

    public Handler getHandler() {
        return handler;
    }

    //静态的引用
    private static MainActivity mMainActivity = null;

    //重写空的构造方法
    public MainActivity() {
        mMainActivity = this;
    }

    //静态方法用来得到当前类的引用
    public static MainActivity getmMainActivity() {
        return mMainActivity;
    }  

服务中启动线程来发送数据

private Thread thread = new Thread(){
    public void run() {
        while (flag) {
            index ++;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Log.i("----------", "-------------------"+index);
            Handler handler = MainActivity.getmMainActivity().getHandler();
            Message msg = handler.obtainMessage();
            msg.what = 1;
            msg.arg1 =index;
            handler.sendMessage(msg);
        }
    };
};  

接口回调的方式

  • 在Service中定义一个CallBack接口中含有抽象方法,包含需要传输的数据
  • 重写MyBinder的时候定义一个CallBack对象和,setCallBack(CallBack back)方法 如下
import java.util.Random;

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

public class ServiceDemo extends Service {
    private int[] bgColor = { Color.RED, Color.CYAN, Color.LTGRAY, Color.GRAY };

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i("------ServiceDemo", "----ServiceDemo");
    }

    private MyBinder binder;

    @Override
    public IBinder onBind(Intent intent) {
        Log.i("--------bind", "----BInd");
        binder = new MyBinder();

        new Thread(){
            public void run() {
                for (int i = 0; i < 10; i++) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    binder.callBack.back("红红火火恍恍惚惚红红火火恍恍惚惚" + i);   //接口回调的方式,可以
                }
            };

        }.start();

        return binder;
    }

    interface CallBack {
        public void back(String str);
    }

    class MyBinder extends Binder {
        private Random random = new Random();
        CallBack callBack;

        public void setCallBack(CallBack callBack) {
            this.callBack = callBack;
        }

        public int getBg() {
            return bgColor[random.nextInt(bgColor.length)];
        }

    }

    @Override
    public void onDestroy() {
        Log.i("--------onDestroy", "----onDestroy");
        super.onDestroy();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.i("--------onUnbind", "----onUnbind");
        return super.onUnbind(intent);
    }
}
  • 在Activity中用bindService方法绑定,然后重写ServiceConncection方法,得到binder对象,然后setCallBack就好了。
MyBinder binder = null;
    ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.i("MainActivity", "----onServiceDisconnected");
        }
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.i("MainActivity", "----onServiceDisconnected");
            binder = (MyBinder) service;
            binder.setCallBack(new CallBack() {

                @Override
                public void back(String str) {
                    Log.i("MainActivity", str);
                }
            });
        }
    };  
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Service与Activity之间通信(学习笔记)

整个项目包括两个文档:MainActivity.java   message.java;注释包括在代码里面,比较简单,就不另作阐述了 MainActivity.java packa...
  • oQianQu
  • oQianQu
  • 2013年10月05日 13:23
  • 610

Android Service与Activity之间通信方式

转载地址http://blog.csdn.net/xiaanming/article/details/9750689 在Android中,Activity主要负责前台页面的展示,Service主要负责...

activity和service之间如何进行通信?

Android的最重要的组件就是Service和Acitivity,那么在使用过程中,我们最常遇到的问题是他们之间的通信问题。 首先Activity调用Service 这个比较基础的,它有两个...

Activity与Service通信(同进程之间)

一、当Acitivity和Service处于同一个Application和进程时,通过继承Binder类来实现。      当一个Activity绑定到一个Service上时,它负责维护Serv...

android学习笔记---service和activity之间通信的几种方式

在Android中,Activity主要负责前台页面的展示,Service主要负责需要长期运行的任务,所以在我们实际开发中,就会常常遇到Activity与Service之间的通信,我们一般在Activ...
  • zrc7151
  • zrc7151
  • 2014年04月24日 09:17
  • 277

Activity与service 之间的通信

三种方式 Bi http://www.tuicool.com/articles/3AVrAz

Service与Activity之间通信的几种方式

转载请注明地址http://blog.csdn.net/xiaanming/article/details/9750689 在Android中,Activity主要负责前台页面的展示,Service...
  • dj0379
  • dj0379
  • 2016年06月05日 14:55
  • 2524

Android Service与Activity之间通信的几种方式

转自 http://blog.csdn.net/xiaanming/article/details/9750689

Android 的Activity和Service之间的通信

在Android中Activity负责前台界面展示,service负责后台的需要长期运行的任务。Activity和Service之间的通信主要由IBinder负责。在需要和Service通信的Acti...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Service和Activity之间的通信
举报原因:
原因补充:

(最多只允许输入30个字)