关闭

Service和Activity之间的通信

标签: android通信service
99人阅读 评论(0) 收藏 举报
分类:

在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);
                }
            });
        }
    };  
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:6952次
    • 积分:451
    • 等级:
    • 排名:千里之外
    • 原创:39篇
    • 转载:0篇
    • 译文:1篇
    • 评论:1条
    文章分类
    最新评论