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