上一篇博客我们简单介绍了一下Android Architecture Component的相关概念与知识点,这篇博客我们将介绍一下如何根据其改造EasyPusher.
EasyPusher的业务逻辑模块是MediaStream类,该类实现摄像头的开启关闭,音频采集的开启关闭,推送的开始和停止的功能.
我们先看看EasyPusher主界面原来的一些关键处理逻辑:
1. onCreate里面进行权限检查,如果尚未获取权限,那弹出获取窗口;
2. onResume里面,检查权限,如果未获取,什么也不做;否则检查Texture,如果有效,开启预览,否则什么也不做;
3. onTextureAvailable ,检查是否有权限,如果没有,什么也不做,否则开启摄像头
4. onPause里面,如果之前开启了预览,那关闭预览;
5. onRequestPermissionsResult,如果权限获取到了,那么再尝试打开摄像头.
6. onDestory里面,检查是否已经开启了.如果没有,什么也不做,否则释放相关资源.
7. 对MediaStream设置一些回调,或者捕获事件,进行MediaStream的状态更新.
综上,可以看到,为了打开摄像头,我们真是煞费苦心,不得不在若干地方进行若干种不同的条件检查.同时,在销毁的时候,也得做出许多非空判断.这导致我们的上层逻辑比较复杂,主Activity的代码里有将近800行.
甚至,之前的Pusher还不支持横竖屏切换的功能,如果支持了,在Activity recreate的时候,要保持摄像头和推送的状态,可能又会带来更多的代码和BUG隐患.
这么多状态检查很痛苦,我们极度期望当我们调用了开始预览后,
==MediaStream能够在内部进行状态检查,在状态都准备好后,自动启动.==
同时,在我们退出Activity后,
==MediaStream能够自动进行资源释放并优雅退出==
基于Architecture Component,MediaStream便可满足上面的期望.我们将对MediaStream做出如下改动:
1. 继承ViewModel.这样使得MediaStream的在Activity的状态更改(比如横竖屏切换)时能自动维护状态;并且在Activity 销毁时,自动得知,从而自己反初始化自己.
// MediaStream.java
// 在Activity Destory的时候,onCleared会自动被调用.这里进行资源释放和自我反初始化
@Override
protected void onCleared() {
super.onCleared();
stopStream(); // 停止推流
stopPreview(); // 停止预览
destroyCamera(); // 关闭摄像头
release(); // 反初始化自己
}
- 上层需要更新的状态通过LiveData进行通知.这里主要有摄像头的当前分辨率\推送开启状态\推送状态\需要监听.因此我们在MediaStream里定义三个LiveData.分别用来表示摄像头分辨率\推送开始状态\推送状态的观察者.
private final CameraPreviewResolutionLiveData cameraPreviewResolution;
private final PushingStateLiveData pushingStateLiveData;
private final StreamingStateLiveData streamingStateLiveData;
同时给上层导出三个LiveData的观察接口:
@MainThread
public void observeCameraPreviewResolution(LifecycleOwner owner, Observer<int[]> observer) {
cameraPreviewResolution.observe(owner, observer);
}
@MainThread
public void observePushingState(LifecycleOwner owner, Observer<PushingState> observer) {
pushingStateLiveData.observe(owner, observer);
}
@MainThread
public void observeStreamingState(LifecycleOwner owner, Observer<Boolean> observer) {
streamingStateLiveData.observe(owner, observer);
}
这样上层Activity可观察这些接口,并进行处理.
观察分辨率更改:
model.observeCameraPreviewResolution(this, new Ob