Android Service与Activity双向通信的两种方式


本博客只讲述同一个进程中activity和Service的通信,进程间通信可以使用AIDL,后续博客更新.
关于Service的认识

service是一种组件,不是单独的线程或者进程,它属于UI线程,只不过当activity被销毁后还可以继续执行,然后在恰当的时刻被系统回收掉,弥补了activity不好管理线程的缺点,若想让Service长久运行,可以使用前台Service,网易云音乐、墨迹天气的通知栏应该都是前台Service,这个不在本博客描述范围内。
方法一:加接口

实际项目写多了慢慢发现了接口的好处,它可以屏蔽两个模块的操作细节,只把功能名称、所携带的参数暴露出来,实现一个接口就是说明当前模块已经实现了某一个功能。那么,如果Service可以提供一个功能,比如说更新进度的功能,把这个功能抽象成一个接口,当activity实现了这个接口的时候,Service就可以向activity传输数据了,即完成了通信。
方法二:广播机制

广播也是解耦和的好方法,Service可以在执行任务过程中发送广播,activity接受到广播后就可以根据接受到的数据进行后续操作。
demo:

代码逻辑比较简单,Service中去执行递增操作,把每次递增的操作反馈给activity
(1)service
在Service中定义了一个接口,并提供了相关的监听方法,开启一个线程执行耗时操作(Service在UI线程运行,耗时操作必须开线程),然后通过handler向主线程发消息,然后调用接口,把数据传给activity。

package com.boomstack.preparehigh.service;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Message;
import android.support.v4.content.LocalBroadcastManager;

import com.boomstack.preparehigh.HolaPrint;

public class MyService extends Service {
    private OnServiceProgressListener listener;
    private Handler handler;

    public MyService() {
    }

    @Override
    public void onCreate() {
        //使用mainlooper 确保在UI线程执行
        handler = new Handler(getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                if (listener != null) {
                    listener.onProgressChanged(msg.what);
                }
            }
        };
    }

    public interface OnServiceProgressListener {
        void onProgressChanged(int progress);
    }

    public void setOnServiceProgressChangedListener(OnServiceProgressListener listener) {
        this.listener = listener;
    }

    /**
     * 递增操作,耗时
     */
    public void increaseNumber() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    try {
                        handler.sendEmptyMessage(i);
                        HolaPrint.pr("耗时操作: " + i);

                        //广播机制通信
                        Intent intent = new Intent("com.boomstack.preparehigh.service");
                        intent.putExtra("extra_data", String.valueOf(i));
                        LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return new MyBinder();
    }

    public class MyBinder extends Binder {
        public MyService getService() {
            return MyService.this;
        }
    }


}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81

(2)activity

package com.boomstack.preparehigh.service;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

import com.boomstack.preparehigh.HolaPrint;
import com.boomstack.preparehigh.R;

public class ServiceActivity extends AppCompatActivity implements MyService.OnServiceProgressListener {

    private MyService myService = null;
    private MyReceiver myReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_service);
        myReceiver = new MyReceiver();
        IntentFilter filter = new IntentFilter("com.boomstack.preparehigh.service");
        LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(myReceiver, filter);
    }

    public void onBindService(View view) {
        ServiceConnection connection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                myService = ((MyService.MyBinder) service).getService();
                myService.setOnServiceProgressChangedListener(ServiceActivity.this);
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {
                HolaPrint.pr("service disconnected.");
            }
        };
        Intent i = new Intent(this, MyService.class);
        bindService(i, connection, BIND_AUTO_CREATE);
    }

    public void onCommunication(View view) {
        myService.increaseNumber();
    }

    @Override
    public void onProgressChanged(int progress) {
        HolaPrint.pr("value via interface: " + progress);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(myReceiver);
    }

    /**
     * 广播接收Service消息
     */
    class MyReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String value = intent.getStringExtra("extra_data");
            HolaPrint.pr("value via broadcast: " + value);
        }
    }
}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76

注:HolaPrint是我自己写的一个类,用于输出的,不必关心。
执行结果:

这里写图片描述
---------------------
作者:Ethan_KF
来源:CSDN
原文:https://blog.csdn.net/ethanhola/article/details/61024992
版权声明:本文为博主原创文章,转载请附上博文链接!


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM