本博客只讲述同一个进程中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
版权声明:本文为博主原创文章,转载请附上博文链接!