Skip to content
This repository was archived by the owner on Feb 6, 2023. It is now read-only.

Commit 1ac65c2

Browse files
committed
refactor: SVGASoundManager 单例模式调整
1 parent ffb1656 commit 1ac65c2

File tree

6 files changed

+84
-72
lines changed

6 files changed

+84
-72
lines changed

app/src/main/java/com/example/ponycui_home/svgaplayer/AnimationFromAssetsActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public void onClick(View view) {
3636
}
3737
});
3838
SVGALogger.INSTANCE.setLogEnabled(true);
39-
SVGASoundManager.Companion.get().init();
39+
SVGASoundManager.INSTANCE.init();
4040
loadAnimation();
4141
setContentView(animationView);
4242
}

library/src/main/java/com/opensource/svgaplayer/SVGADrawable.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ class SVGADrawable(val videoItem: SVGAVideoEntity, val dynamicItem: SVGADynamicE
5757
fun resume() {
5858
videoItem.audioList.forEach { audio ->
5959
audio.playID?.let {
60-
if (SVGASoundManager.get().isInit()){
61-
SVGASoundManager.get().resume(it)
60+
if (SVGASoundManager.isInit()){
61+
SVGASoundManager.resume(it)
6262
}else{
6363
videoItem.soundPool?.resume(it)
6464
}
@@ -69,8 +69,8 @@ class SVGADrawable(val videoItem: SVGAVideoEntity, val dynamicItem: SVGADynamicE
6969
fun pause() {
7070
videoItem.audioList.forEach { audio ->
7171
audio.playID?.let {
72-
if (SVGASoundManager.get().isInit()){
73-
SVGASoundManager.get().pause(it)
72+
if (SVGASoundManager.isInit()){
73+
SVGASoundManager.pause(it)
7474
}else{
7575
videoItem.soundPool?.pause(it)
7676
}
@@ -81,8 +81,8 @@ class SVGADrawable(val videoItem: SVGAVideoEntity, val dynamicItem: SVGADynamicE
8181
fun stop() {
8282
videoItem.audioList.forEach { audio ->
8383
audio.playID?.let {
84-
if (SVGASoundManager.get().isInit()){
85-
SVGASoundManager.get().stop(it)
84+
if (SVGASoundManager.isInit()){
85+
SVGASoundManager.stop(it)
8686
}else{
8787
videoItem.soundPool?.stop(it)
8888
}
@@ -93,8 +93,8 @@ class SVGADrawable(val videoItem: SVGAVideoEntity, val dynamicItem: SVGADynamicE
9393
fun clear() {
9494
videoItem.audioList.forEach { audio ->
9595
audio.playID?.let {
96-
if (SVGASoundManager.get().isInit()){
97-
SVGASoundManager.get().stop(it)
96+
if (SVGASoundManager.isInit()){
97+
SVGASoundManager.stop(it)
9898
}else{
9999
videoItem.soundPool?.stop(it)
100100
}

library/src/main/java/com/opensource/svgaplayer/SVGAParser.kt

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import android.content.Context
44
import android.net.http.HttpResponseCache
55
import android.os.Handler
66
import android.os.Looper
7-
import android.util.Log
87
import com.opensource.svgaplayer.proto.MovieEntity
98
import com.opensource.svgaplayer.utils.log.LogUtils
109
import org.json.JSONObject
@@ -20,7 +19,6 @@ import java.util.zip.ZipInputStream
2019
/**
2120
* Created by PonyCui 16/6/18.
2221
*/
23-
2422
private var fileLock: Int = 0
2523
private var isUnzipping = false
2624

@@ -134,21 +132,32 @@ class SVGAParser(context: Context?) {
134132
mFrameHeight = frameHeight
135133
}
136134

137-
fun decodeFromAssets(name: String, callback: ParseCompletion?,playCallback: PlayCallback?=null) {
135+
fun decodeFromAssets(
136+
name: String,
137+
callback: ParseCompletion?,
138+
playCallback: PlayCallback? = null
139+
) {
138140
if (mContext == null) {
139141
LogUtils.error(TAG, "在配置 SVGAParser context 前, 无法解析 SVGA 文件。")
140142
return
141143
}
142-
try {
143-
LogUtils.info(TAG, "================ decode from assets ================")
144-
threadPoolExecutor.execute {
144+
LogUtils.info(TAG, "================ decode from assets ================")
145+
threadPoolExecutor.execute {
146+
try {
145147
mContext?.assets?.open(name)?.let {
146-
this.decodeFromInputStream(it, SVGACache.buildCacheKey("file:///assets/$name"), callback, true,playCallback)
148+
this.decodeFromInputStream(
149+
it,
150+
SVGACache.buildCacheKey("file:///assets/$name"),
151+
callback,
152+
true,
153+
playCallback
154+
)
147155
}
156+
} catch (e: java.lang.Exception) {
157+
this.invokeErrorCallback(e, callback)
148158
}
149-
} catch (e: java.lang.Exception) {
150-
this.invokeErrorCallback(e, callback)
151159
}
160+
152161
}
153162

154163
fun decodeFromURL(url: URL, callback: ParseCompletion?,playCallback: PlayCallback?=null): (() -> Unit)? {
@@ -234,8 +243,8 @@ class SVGAParser(context: Context?) {
234243
fun _decodeFromInputStream(
235244
inputStream: InputStream,
236245
cacheKey: String,
237-
callback: ParseCompletion?
238-
,playCallback: PlayCallback?
246+
callback: ParseCompletion?,
247+
playCallback: PlayCallback?
239248
) {
240249
threadPoolExecutor.execute {
241250
try {
@@ -269,7 +278,7 @@ class SVGAParser(context: Context?) {
269278
videoItem.prepare({
270279
LogUtils.info(TAG, "cache.prepare success")
271280
this.invokeCompleteCallback(videoItem, callback)
272-
},playCallback)
281+
}, playCallback)
273282
} ?: doError("Input.inflate(bytes) cause exception", callback)
274283
} ?: doError("Input.readAsBytes(inputStream) cause exception", callback)
275284
} catch (e: Exception) {

library/src/main/java/com/opensource/svgaplayer/SVGASoundManager.kt

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ import java.io.FileDescriptor
1515
/**
1616
* Author : llk
1717
* Time : 2020/10/24
18-
* Description : svga音频加载管理类
19-
* 将SoundPool抽取到单例里边,规避load资源之后不回调onLoadComplete的问题
18+
* Description : svga 音频加载管理类
19+
* 将 SoundPool 抽取到单例里边,规避 load 资源之后不回调 onLoadComplete 的问题
2020
*
21-
* 需要对SVGASoundManager进行初始化
21+
* 需要对 SVGASoundManager 进行初始化
2222
*
23-
* 相关文章:Android SoundPool崩溃问题研究
23+
* 相关文章:Android SoundPool 崩溃问题研究
2424
* https://zhuanlan.zhihu.com/p/29985198
2525
*/
26-
class SVGASoundManager private constructor(){
26+
object SVGASoundManager {
2727

2828
private val TAG = SVGASoundManager::class.java.simpleName
2929

@@ -46,18 +46,18 @@ class SVGASoundManager private constructor(){
4646
fun onComplete()
4747
}
4848

49-
fun init(){
49+
fun init() {
5050
init(20)
5151
}
5252

53-
fun init(maxStreams : Int) {
53+
fun init(maxStreams: Int) {
5454
LogUtils.debug(TAG, "**************** init **************** $maxStreams")
55-
if(soundPool!=null){
55+
if (soundPool != null) {
5656
return
5757
}
5858
soundPool = getSoundPool(maxStreams)
5959
soundPool?.setOnLoadCompleteListener { _, soundId, status ->
60-
LogUtils.info(TAG, "SoundPool onLoadComplete soundId=$soundId status=$status")
60+
LogUtils.debug(TAG, "SoundPool onLoadComplete soundId=$soundId status=$status")
6161
if (status == 0) { //加载该声音成功
6262
if (completeCallBackMap.containsKey(soundId)) {
6363
completeCallBackMap[soundId]?.onComplete()
@@ -66,7 +66,7 @@ class SVGASoundManager private constructor(){
6666
}
6767
}
6868

69-
fun release(){
69+
fun release() {
7070
LogUtils.debug(TAG, "**************** release ****************")
7171
if (completeCallBackMap.isNotEmpty()){
7272
completeCallBackMap.clear()
@@ -76,21 +76,21 @@ class SVGASoundManager private constructor(){
7676
/**
7777
* 是否初始化
7878
* 如果没有初始化,就使用原来SvgaPlayer库的音频加载逻辑。
79-
* @return -
79+
* @return true 则已初始化, 否则为 false
8080
*/
81-
fun isInit() :Boolean{
81+
internal fun isInit(): Boolean {
8282
return soundPool != null
8383
}
8484

85-
private fun checkInit() :Boolean{
85+
private fun checkInit(): Boolean {
8686
val isInit = isInit()
8787
if (!isInit) {
8888
LogUtils.error(TAG, "soundPool is null, you need call init() !!!")
8989
}
9090
return isInit
9191
}
9292

93-
private fun getSoundPool(maxStreams : Int) = if (Build.VERSION.SDK_INT >= 21) {
93+
private fun getSoundPool(maxStreams: Int) = if (Build.VERSION.SDK_INT >= 21) {
9494
val attributes = AudioAttributes.Builder()
9595
.setUsage(AudioAttributes.USAGE_MEDIA)
9696
.build()
@@ -110,18 +110,18 @@ class SVGASoundManager private constructor(){
110110

111111
val soundId = soundPool!!.load(fd, offset, length, priority)
112112

113-
LogUtils.info(TAG, "load soundId=$soundId callBack=$callBack")
113+
LogUtils.debug(TAG, "load soundId=$soundId callBack=$callBack")
114114

115115
if (callBack != null && !completeCallBackMap.containsKey(soundId)) {
116116
completeCallBackMap[soundId] = callBack
117117
}
118118
return soundId
119119
}
120120

121-
fun unload(soundId: Int) {
121+
internal fun unload(soundId: Int) {
122122
if (!checkInit()) return
123123

124-
LogUtils.info(TAG, "unload soundId=$soundId")
124+
LogUtils.debug(TAG, "unload soundId=$soundId")
125125

126126
soundPool!!.unload(soundId)
127127

@@ -140,21 +140,21 @@ class SVGASoundManager private constructor(){
140140
return soundPool!!.play(soundId, leftVolume, rightVolume, priority, loop, rate)
141141
}
142142

143-
fun stop(soundId: Int) {
143+
internal fun stop(soundId: Int) {
144144
if (!checkInit()) return
145145

146146
LogUtils.debug(TAG, "stop soundId=$soundId")
147147
soundPool!!.stop(soundId)
148148
}
149149

150-
fun resume(soundId: Int) {
150+
internal fun resume(soundId: Int) {
151151
if (!checkInit()) return
152152

153153
LogUtils.debug(TAG, "stop soundId=$soundId")
154154
soundPool!!.resume(soundId)
155155
}
156156

157-
fun pause(soundId: Int) {
157+
internal fun pause(soundId: Int) {
158158
if (!checkInit()) return
159159

160160
LogUtils.debug(TAG, "pause soundId=$soundId")

library/src/main/java/com/opensource/svgaplayer/SVGAVideoEntity.kt

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ import android.media.AudioAttributes
55
import android.media.AudioManager
66
import android.media.SoundPool
77
import android.os.Build
8-
import android.os.Handler
9-
import android.util.Log
108
import com.opensource.svgaplayer.bitmap.SVGABitmapByteArrayDecoder
119
import com.opensource.svgaplayer.bitmap.SVGABitmapFileDecoder
1210
import com.opensource.svgaplayer.entities.SVGAAudioEntity
@@ -28,6 +26,8 @@ import kotlin.collections.ArrayList
2826
*/
2927
class SVGAVideoEntity {
3028

29+
private val TAG = "SVGAVideoEntity"
30+
3131
var antiAlias = true
3232
var movieItem: MovieEntity? = null
3333

@@ -105,9 +105,9 @@ class SVGAVideoEntity {
105105
frames = movieParams.frames ?: 0
106106
}
107107

108-
internal fun prepare(callback: () -> Unit,playCallback: SVGAParser.PlayCallback?) {
109-
mCallback=callback
110-
mPlayCallback=playCallback
108+
internal fun prepare(callback: () -> Unit, playCallback: SVGAParser.PlayCallback?) {
109+
mCallback = callback
110+
mPlayCallback = playCallback
111111
if (movieItem == null) {
112112
mCallback()
113113
} else {
@@ -198,7 +198,7 @@ class SVGAVideoEntity {
198198
val audiosFileMap = generateAudioFileMap(entity)
199199
//repair when audioEntity error can not callback
200200
//如果audiosFileMap为空 soundPool?.load 不会走 导致 setOnLoadCompleteListener 不会回调 导致外层prepare不回调卡住
201-
if(audiosFileMap.size==0 ){
201+
if (audiosFileMap.size == 0) {
202202
run(completionBlock)
203203
return
204204
}
@@ -215,30 +215,28 @@ class SVGAVideoEntity {
215215
// 除数不能为 0
216216
return item
217217
}
218-
//直接回调文件,后续播放都不走
218+
// 直接回调文件,后续播放都不走
219219
mPlayCallback?.let {
220-
val fileList:MutableList<File> =ArrayList()
221-
audiosFileMap.forEach{entity->
220+
val fileList: MutableList<File> = ArrayList()
221+
audiosFileMap.forEach { entity ->
222222
fileList.add(entity.value)
223223
}
224224
it.onPlay(fileList)
225225
mCallback()
226226
return item
227227
}
228-
audiosFileMap[audio.audioKey]?.let { file ->
229228

229+
audiosFileMap[audio.audioKey]?.let { file ->
230230
FileInputStream(file).use {
231231
val length = it.available().toDouble()
232232
val offset = ((startTime / totalTime) * length).toLong()
233-
if (SVGASoundManager.get().isInit()) {
234-
Log.e("aaaa", "SVGASoundManager load"+System.currentTimeMillis() )
235-
item.soundID = SVGASoundManager.get().load(soundCallback,
233+
if (SVGASoundManager.isInit()) {
234+
item.soundID = SVGASoundManager.load(soundCallback,
236235
it.fd,
237236
offset,
238237
length.toLong(),
239238
1)
240239
} else {
241-
Log.e("aaaa", "soundPool load"+System.currentTimeMillis() )
242240
item.soundID = soundPool?.load(it.fd, offset, length.toLong(), 1)
243241
}
244242
}
@@ -291,7 +289,6 @@ class SVGAVideoEntity {
291289
if (SVGASoundManager.get().isInit()) {
292290
soundCallback = object : SVGASoundManager.CompleteCallBack {
293291
override fun onComplete() {
294-
Log.e("aaaa", "SVGASoundManager pool_complete$soundLoaded"+entity.audios.count()+completionBlock)
295292
soundLoaded++
296293
if (soundLoaded >= entity.audios.count()) {
297294
completionBlock()
@@ -303,7 +300,6 @@ class SVGAVideoEntity {
303300
soundPool = generateSoundPool(entity)
304301
LogUtils.info("SVGAParser", "pool_start")
305302
soundPool?.setOnLoadCompleteListener { _, _, _ ->
306-
Log.e("aaaa", "soundPool pool_complete $soundLoaded" )
307303
LogUtils.info("SVGAParser", "pool_complete")
308304
soundLoaded++
309305
if (soundLoaded >= entity.audios.count()) {
@@ -312,21 +308,28 @@ class SVGAVideoEntity {
312308
}
313309
}
314310

315-
private fun generateSoundPool(entity: MovieEntity) = if (Build.VERSION.SDK_INT >= 21) {
316-
val attributes = AudioAttributes.Builder()
317-
.setUsage(AudioAttributes.USAGE_MEDIA)
318-
.build()
319-
SoundPool.Builder().setAudioAttributes(attributes)
320-
.setMaxStreams(12.coerceAtMost(entity.audios.count()))
321-
.build()
322-
} else {
323-
SoundPool(12.coerceAtMost(entity.audios.count()), AudioManager.STREAM_MUSIC, 0)
311+
private fun generateSoundPool(entity: MovieEntity): SoundPool? {
312+
return try {
313+
if (Build.VERSION.SDK_INT >= 21) {
314+
val attributes = AudioAttributes.Builder()
315+
.setUsage(AudioAttributes.USAGE_MEDIA)
316+
.build()
317+
SoundPool.Builder().setAudioAttributes(attributes)
318+
.setMaxStreams(12.coerceAtMost(entity.audios.count()))
319+
.build()
320+
} else {
321+
SoundPool(12.coerceAtMost(entity.audios.count()), AudioManager.STREAM_MUSIC, 0)
322+
}
323+
} catch (e: Exception) {
324+
LogUtils.error(TAG, e)
325+
null
326+
}
324327
}
325328

326329
fun clear() {
327-
if (SVGASoundManager.get().isInit()) {
330+
if (SVGASoundManager.isInit()) {
328331
this.audioList.forEach {
329-
it.soundID?.let { id -> SVGASoundManager.get().unload(id) }
332+
it.soundID?.let { id -> SVGASoundManager.unload(id) }
330333
}
331334
soundCallback = null
332335
}

0 commit comments

Comments
 (0)