使用 Service 解耦 Activity

需求

高耦合 Activity 搞定需求

解耦 Activity 搞定需求

问题

在第一个 Activity(A)中启动第二个 Activity(B)后,未调用 finish(),所以在启动 B 后,A、B 是共存的,B 盖在 A 上面,用户可见的是 B。当用户点击【上传】后,需立刻显示 A,并进行上传,此时有几种选择:

1、直接杀掉 B,显示 A。该方式上传不能进行。

2、将图片通过 intent 或内置存储传递,在 A 上传。该方式受 intent 传递大小小于 1 MB 限制,通过内置存储传递写入、再读取的时间损失比较大。

3、等待上传完成,再杀掉 B。该方式不能立刻显示 A。

4、直接杀掉 A,在 B 中启动第一个 Activity(A’),等待上传完成,再杀掉 B,上传结果通过 BroadcastReceiver 告诉 A’。该方式可行,但是第一个 Activity 需要再初始化一次,且上传过程不易控(因为上传是在 B,现在切换到 A’ 了,而 A’ 和 B 交互比较麻烦)。

5、使用 Service。

使用 Service 解决问题

A 绑定 Service,并设置上传成功和失败的回调,当用户点击【上传】后,B 绑定 Service,将图片通过 Service 上传,并直接关闭 B。

1、用于上传的 Service(以存到内置存储中为例)

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
public class MyService extends Service {
private static String TAG = "MyService";
private MyBinder mMyBinder = new MyBinder();
@Override
public IBinder onBind(Intent intent) {
return mMyBinder;
}
public class MyBinder extends Binder {
private MyListener mMyListener;
public void setListener(MyListener myListener) {
mMyListener = myListener;
}
public void submit(final Bitmap bitmap) {
if (bitmap != null) {
new Thread(new Runnable() {
@Override
public void run() {
FileOutputStream out = null;
try {
String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "temp.jpg";
File file = new File(filePath);
file.createNewFile();
out = new FileOutputStream(filePath);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
if (mMyListener != null) {
mMyListener.onSuccess();
}
} catch (Exception e) {
if (mMyListener != null) {
mMyListener.onFailed(e.getMessage());
}
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}).start();
}
}
}
public interface MyListener {
void onSuccess();
void onFailed(String msg);
}
}

2、A 绑定 Service,并设置上传成功和失败的回调

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
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mMyBinder = (MyService.MyBinder) service;
mMyBinder.setListener(MainActivity.this);
}
@Override
public void onServiceDisconnected(ComponentName name) {
mMyBinder.setListener(null);
}
};
private void bindService() {
Intent intent = new Intent(this, MyService.class);
bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
}
private void unbindService() {
if (mServiceConnection != null) {
unbindService(mServiceConnection);
}
}
@Override
public void onSuccess() {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "success!", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onFailed(final String msg) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "failed!" + msg, Toast.LENGTH_SHORT).show();
}
});
}

3、当用户点击【上传】后,B 绑定 Service,将图片通过 Service 上传,并直接关闭 B

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
private ServiceConnection mServiceConnection;
private void bindService() {
Intent intent = new Intent(this, MyService.class);
bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
}
private void unbindService() {
if (mServiceConnection != null) {
unbindService(mServiceConnection);
}
}
public void submit(final Bitmap bitmap) {
mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mMyBinder = (MyService.MyBinder) service;
mMyBinder.submit(bitmap);
CameraActivity.this.finish();
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
bindService();
}

本文标题:使用 Service 解耦 Activity

文章作者:魏超

发布时间:2017年11月15日 - 21:11

最后更新:2018年12月07日 - 19:12

原始链接:http://www.weichao.io/2017/11/15/使用-Service-解耦-Activity/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

---------------------本文结束---------------------