@@ -180,148 +180,79 @@ class SVGAParser(context: Context?) {
180
180
if (SVGACache .isDefaultCache()) {
181
181
this .decodeFromCacheKey(cacheKey, callback, alias = urlPath)
182
182
} else {
183
- this ._decodeFromCacheKey (cacheKey, callback, playCallback, alias = urlPath)
183
+ this .decodeFromSVGAFileCacheKey (cacheKey, callback, playCallback, alias = urlPath)
184
184
}
185
185
}
186
186
return null
187
187
} else {
188
188
LogUtils .info(TAG , " no cached, prepare to download" )
189
189
fileDownloader.resume(url, {
190
- if (SVGACache .isDefaultCache()) {
191
- this .decodeFromInputStream(
192
- it,
193
- cacheKey,
194
- callback,
195
- false ,
196
- playCallback,
197
- alias = urlPath
198
- )
199
- } else {
200
- this ._decodeFromInputStream (
201
- it,
202
- cacheKey,
203
- callback,
204
- playCallback,
205
- alias = urlPath
206
- )
207
- }
190
+ this .decodeFromInputStream(
191
+ it,
192
+ cacheKey,
193
+ callback,
194
+ false ,
195
+ playCallback,
196
+ alias = urlPath
197
+ )
208
198
}, {
209
199
LogUtils .error(
210
- TAG ,
211
- " ================ svga file: $url download fail ================"
200
+ TAG ,
201
+ " ================ svga file: $url download fail ================"
212
202
)
213
203
this .invokeErrorCallback(it, callback, alias = urlPath)
214
204
})
215
205
}
216
206
}
217
207
218
208
/* *
219
- * 读取解析本地缓存的svga文件 .
209
+ * 读取解析本地缓存的 svga 文件 .
220
210
*/
221
- fun _decodeFromCacheKey (
211
+ fun decodeFromSVGAFileCacheKey (
222
212
cacheKey : String ,
223
213
callback : ParseCompletion ? ,
224
214
playCallback : PlayCallback ? ,
225
215
alias : String? = null
226
216
) {
227
- val svga = SVGACache .buildSvgaFile(cacheKey)
228
- try {
229
- LogUtils .info(TAG , " $alias cache.binary change to entity" )
230
- FileInputStream (svga).use { inputStream ->
231
- try {
217
+ threadPoolExecutor.execute {
218
+ try {
219
+ LogUtils .info(TAG , " ================ decode $alias from svga cachel file to entity ================" )
220
+ FileInputStream (SVGACache .buildSvgaFile(cacheKey)).use { inputStream ->
232
221
readAsBytes(inputStream)?.let { bytes ->
233
- LogUtils .info(TAG , " cache.inflate start" )
234
- inflate(bytes)?.let { inflateBytes ->
235
- LogUtils .info(TAG , " cache.inflate success" )
236
- val videoItem = SVGAVideoEntity (
237
- MovieEntity .ADAPTER .decode(inflateBytes),
222
+ if (isZipFile(bytes)) {
223
+ this .decodeFromCacheKey(cacheKey, callback, alias)
224
+ } else {
225
+ LogUtils .info(TAG , " inflate start" )
226
+ inflate(bytes)?.let {
227
+ LogUtils .info(TAG , " inflate complete" )
228
+ val videoItem = SVGAVideoEntity (
229
+ MovieEntity .ADAPTER .decode(it),
238
230
File (cacheKey),
239
231
mFrameWidth,
240
232
mFrameHeight
233
+ )
234
+ LogUtils .info(TAG , " SVGAVideoEntity prepare start" )
235
+ videoItem.prepare({
236
+ LogUtils .info(TAG , " SVGAVideoEntity prepare success" )
237
+ this .invokeCompleteCallback(videoItem, callback, alias)
238
+ },playCallback)
239
+
240
+ } ? : this .invokeErrorCallback(
241
+ Exception (" inflate(bytes) cause exception" ),
242
+ callback,
243
+ alias
241
244
)
242
- videoItem.prepare({
243
- LogUtils .info(TAG , " cache.prepare success" )
244
- this .invokeCompleteCallback(videoItem, callback, alias)
245
- },playCallback)
246
- } ? : doError(" cache.inflate(bytes) cause exception" , callback, alias)
247
- } ? : doError(" cache.readAsBytes(inputStream) cause exception" , callback, alias)
248
- } catch (e: Exception ) {
249
- this .invokeErrorCallback(e, callback, alias)
250
- } finally {
251
- inputStream.close()
252
- }
253
- }
254
- } catch (e: Exception ) {
255
- LogUtils .error(TAG , " $alias cache.binary change to entity fail" , e)
256
- svga.takeIf { it.exists() }?.delete()
257
- this .invokeErrorCallback(e, callback, alias)
258
- }
259
- }
260
-
261
- private fun doError (
262
- error : String ,
263
- callback : ParseCompletion ? ,
264
- alias : String?
265
- ) {
266
- LogUtils .info(TAG , error)
267
- this .invokeErrorCallback(
268
- Exception (error),
269
- callback,
270
- alias
271
- )
272
- }
273
-
274
- /* *
275
- * 读取解析来自URL的svga文件.并缓存成本地文件
276
- */
277
- fun _decodeFromInputStream (
278
- inputStream : InputStream ,
279
- cacheKey : String ,
280
- callback : ParseCompletion ? ,
281
- playCallback : PlayCallback ? ,
282
- alias : String? = null
283
- ) {
284
- threadPoolExecutor.execute {
285
- try {
286
- LogUtils .info(TAG , " ================ $alias _inputStream change to entity ================" )
287
- readAsBytes(inputStream)?.let { bytes ->
288
- threadPoolExecutor.execute {
289
- SVGACache .buildSvgaFile(cacheKey).let { cacheFile ->
290
- try {
291
- cacheFile.takeIf { ! it.exists() }?.createNewFile()
292
- FileOutputStream (cacheFile).write(bytes)
293
- } catch (e: Exception ) {
294
- LogUtils .error(TAG , " create cache file fail." , e)
295
- cacheFile.delete()
296
- }
297
245
}
298
- }
299
- LogUtils .info(TAG , " inputStream inflate start" )
300
- inflate(bytes)?.let { inflateBytes ->
301
- LogUtils .info(TAG , " inputStream inflate success" )
302
- val videoItem = SVGAVideoEntity (
303
- MovieEntity .ADAPTER .decode(inflateBytes),
304
- File (cacheKey),
305
- mFrameWidth,
306
- mFrameHeight
307
- )
308
- // 里面soundPool如果解析时load同一个svga的声音文件会出现无回调的情况,导致这里的callback不执行,
309
- // 原因暂时未知.目前解决方案是公开imageview,drawable,entity的clear(),然后在播放带声音
310
- // 的svgaimageview处,把解析完的drawable或者entity缓存下来,下次直接播放.用完再调用clear()
311
- // 在ImageView添加clearsAfterDetached,用于控制imageview在onDetach的时候是否要自动调用clear.
312
- // 以暂时缓解需要为RecyclerView缓存drawable或者entity的人士.用完记得调用clear()
313
- LogUtils .info(TAG , " SVGAVideoEntity prepare start" )
314
- videoItem.prepare({
315
- LogUtils .info(TAG , " SVGAVideoEntity prepare success" )
316
- this .invokeCompleteCallback(videoItem, callback, alias)
317
- }, playCallback)
318
- } ? : doError(" inflate(bytes) cause exception" , callback, alias)
319
- } ? : doError(" readAsBytes(inputStream) cause exception" , callback, alias)
320
- } catch (e: Exception ) {
246
+ } ? : this .invokeErrorCallback(
247
+ Exception (" readAsBytes(inputStream) cause exception" ),
248
+ callback,
249
+ alias
250
+ )
251
+ }
252
+ } catch (e: java.lang.Exception ) {
321
253
this .invokeErrorCallback(e, callback, alias)
322
254
} finally {
323
- inputStream.close()
324
- LogUtils .info(TAG , " ================ $alias _inputStream change to entity end ================" )
255
+ LogUtils .info(TAG , " ================ decode $alias from svga cachel file to entity end ================" )
325
256
}
326
257
}
327
258
}
@@ -331,7 +262,7 @@ class SVGAParser(context: Context?) {
331
262
cacheKey : String ,
332
263
callback : ParseCompletion ? ,
333
264
closeInputStream : Boolean = false,
334
- playCallback : PlayCallback ? = null,
265
+ playCallback : PlayCallback ? = null,
335
266
alias : String? = null
336
267
) {
337
268
if (mContext == null ) {
@@ -342,7 +273,7 @@ class SVGAParser(context: Context?) {
342
273
threadPoolExecutor.execute {
343
274
try {
344
275
readAsBytes(inputStream)?.let { bytes ->
345
- if (bytes.size > 4 && bytes[ 0 ].toInt() == 80 && bytes[ 1 ].toInt() == 75 && bytes[ 2 ].toInt() == 3 && bytes[ 3 ].toInt() == 4 ) {
276
+ if (isZipFile( bytes) ) {
346
277
LogUtils .info(TAG , " decode from zip file" )
347
278
if (! SVGACache .buildCacheDir(cacheKey).exists() || isUnzipping) {
348
279
synchronized(fileLock) {
@@ -359,6 +290,20 @@ class SVGAParser(context: Context?) {
359
290
}
360
291
this .decodeFromCacheKey(cacheKey, callback, alias)
361
292
} else {
293
+ if (! SVGACache .isDefaultCache()) {
294
+ // 如果 SVGACache 设置类型为 FILE
295
+ threadPoolExecutor.execute {
296
+ SVGACache .buildSvgaFile(cacheKey).let { cacheFile ->
297
+ try {
298
+ cacheFile.takeIf { ! it.exists() }?.createNewFile()
299
+ FileOutputStream (cacheFile).write(bytes)
300
+ } catch (e: Exception ) {
301
+ LogUtils .error(TAG , " create cache file fail." , e)
302
+ cacheFile.delete()
303
+ }
304
+ }
305
+ }
306
+ }
362
307
LogUtils .info(TAG , " inflate start" )
363
308
inflate(bytes)?.let {
364
309
LogUtils .info(TAG , " inflate complete" )
@@ -561,6 +506,12 @@ class SVGAParser(context: Context?) {
561
506
}
562
507
}
563
508
509
+ // 是否是 zip 文件
510
+ private fun isZipFile (bytes : ByteArray ): Boolean {
511
+ return bytes.size > 4 && bytes[0 ].toInt() == 80 && bytes[1 ].toInt() == 75 && bytes[2 ].toInt() == 3 && bytes[3 ].toInt() == 4
512
+ }
513
+
514
+ // 解压
564
515
private fun unzip (inputStream : InputStream , cacheKey : String ) {
565
516
LogUtils .info(TAG , " ================ unzip prepare ================" )
566
517
val cacheDir = SVGACache .buildCacheDir(cacheKey)
0 commit comments