本博客只講述同一個進程中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
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!