From db2194fe020c825eb159bdbc566ed830088f0f37 Mon Sep 17 00:00:00 2001 From: eggmanQQQ <3671373519@qq.com> Date: Wed, 5 Feb 2025 15:58:43 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=B0=9D=E8=AF=95=E4=BC=98=E5=8C=96=20b?= =?UTF-8?q?anner=20+=20svga=20=E7=9A=84=E5=86=85=E5=AD=98=E5=8D=A0?= =?UTF-8?q?=E7=94=A8,=20=E6=B7=BB=E5=8A=A0=E8=B5=84=E6=BA=90=E5=9B=9E?= =?UTF-8?q?=E6=94=B6=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../avroom/adapter/RoomNormalListAdapter.java | 4 +- .../app/home/adapter/HomeBannerAdapter.kt | 3 + .../java/com/chwl/app/utils/AnimLoadUtil.kt | 35 +-- .../com/chwl/app/utils/ResourceManager.kt | 7 +- .../main/java/com/chwl/app/view/EffectView.kt | 221 ++++++++++++------ .../icon_dialog_mark_black_list.webp | Bin 1789 -> 0 bytes .../java/com/chwl/core/gift/GiftModel.java | 21 +- .../chwl/core/manager/IMNetEaseManager.java | 2 +- .../java/com/chwl/library/widget/SVGAView.kt | 2 +- 9 files changed, 188 insertions(+), 107 deletions(-) delete mode 100644 app/src/main/res/drawable-xhdpi/icon_dialog_mark_black_list.webp diff --git a/app/src/main/java/com/chwl/app/avroom/adapter/RoomNormalListAdapter.java b/app/src/main/java/com/chwl/app/avroom/adapter/RoomNormalListAdapter.java index 0b4d8a772..df304a219 100644 --- a/app/src/main/java/com/chwl/app/avroom/adapter/RoomNormalListAdapter.java +++ b/app/src/main/java/com/chwl/app/avroom/adapter/RoomNormalListAdapter.java @@ -59,9 +59,9 @@ public class RoomNormalListAdapter extends RecyclerView.Adapter() { val effectView = helper.findViewById(R.id.effectView) effectView.load(item?.bannerPic?:"",item?.fillVo?.imgMap,item?.fillVo?.textMap) } + + + } \ No newline at end of file diff --git a/app/src/main/java/com/chwl/app/utils/AnimLoadUtil.kt b/app/src/main/java/com/chwl/app/utils/AnimLoadUtil.kt index 8815c330e..5caa26915 100644 --- a/app/src/main/java/com/chwl/app/utils/AnimLoadUtil.kt +++ b/app/src/main/java/com/chwl/app/utils/AnimLoadUtil.kt @@ -55,23 +55,26 @@ object AnimLoadUtil { } fun isSvgaFile(path: String,callBack: (isSvga: Boolean,videoItem: SVGAVideoEntity?) -> Unit = {_,_->}){ - val inputStream = BufferedInputStream(FileInputStream(path)) - shareParser().decodeFromInputStream( - inputStream, - path, - object : SVGAParser.ParseCompletion { - override fun onComplete(videoItem: SVGAVideoEntity) { - callBack(true,videoItem) - } + try { + val inputStream = BufferedInputStream(FileInputStream(path)) + shareParser().decodeFromInputStream( + inputStream, + path, + object : SVGAParser.ParseCompletion { + override fun onComplete(videoItem: SVGAVideoEntity) { + callBack(true,videoItem) + } - override fun onError() { - callBack(false,null) - } - }, - true, - null, - null - ) + override fun onError() { + callBack(false,null) + } + }, + true, + null, + null + ) + } catch (e: Exception) { + } } //垃圾 不顶用 diff --git a/app/src/main/java/com/chwl/app/utils/ResourceManager.kt b/app/src/main/java/com/chwl/app/utils/ResourceManager.kt index 66180c1e8..0c556ba5e 100644 --- a/app/src/main/java/com/chwl/app/utils/ResourceManager.kt +++ b/app/src/main/java/com/chwl/app/utils/ResourceManager.kt @@ -20,6 +20,7 @@ import java.io.File object ResourceManager { public var mClientResource : ClientResource? = null + private val needLog = false; fun initResource() { InitialModel.get().clientResource().doOnSuccess { @@ -73,7 +74,7 @@ object ResourceManager { private fun doLoad(url: String) { if (url.isVerify()) { - "预加载 -> ResourceManager doLoad url = $url".doLog() + "预加载 -> ResourceManager doLoad url = $url".doLog(needLog) GlideUtils.instance().downloadFromUrl2(AppUtils.getApp(),url,object : RequestListener { override fun onLoadFailed( e: GlideException?, @@ -81,7 +82,7 @@ object ResourceManager { target: Target?, isFirstResource: Boolean ): Boolean { - "预加载 -> ResourceManager onLoadFailed error = ${e?.message} url = $url".doLog() + "预加载 -> ResourceManager onLoadFailed error = ${e?.message} url = $url".doLog(needLog) return true } @@ -92,7 +93,7 @@ object ResourceManager { dataSource: DataSource?, isFirstResource: Boolean ): Boolean { - "预加载 -> ResourceManager onResourceReady Success url = $url".doLog() + "预加载 -> ResourceManager onResourceReady Success url = $url".doLog(needLog) return true } }) diff --git a/app/src/main/java/com/chwl/app/view/EffectView.kt b/app/src/main/java/com/chwl/app/view/EffectView.kt index 1758be57c..cf54c10f8 100644 --- a/app/src/main/java/com/chwl/app/view/EffectView.kt +++ b/app/src/main/java/com/chwl/app/view/EffectView.kt @@ -13,6 +13,7 @@ import android.text.StaticLayout import android.text.TextPaint import android.text.TextUtils import android.util.AttributeSet +import android.util.LruCache import android.view.View import android.view.ViewGroup import android.widget.FrameLayout @@ -37,6 +38,7 @@ import com.netease.nim.uikit.support.glide.GlideApp import com.opensource.svgaplayer.SVGACallback import com.opensource.svgaplayer.SVGADrawable import com.opensource.svgaplayer.SVGADynamicEntity +import com.opensource.svgaplayer.SVGAImageView import com.opensource.svgaplayer.SVGAParser import com.opensource.svgaplayer.SVGAParser.Companion.shareParser import com.opensource.svgaplayer.SVGAVideoEntity @@ -60,6 +62,7 @@ class EffectView : FrameLayout { var mCallBack : CallBack? = null var hasAnimImg = false; // 图片是否可能带 序列帧动图 + var mPlayerCount = 1; private var mResourceUrl = "" private var mEffectType = EffectType.IMG @@ -71,6 +74,10 @@ class EffectView : FrameLayout { private var mNeedLog = false + private var mImage : ImageView? = null + private var mSvga : SVGAView? = null + private var mVap : AnimView? = null + private fun init(context: Context) { } @@ -119,7 +126,7 @@ class EffectView : FrameLayout { } else { loadEffect(EffectType.MP4,resource) } - } + } } } } else { @@ -153,14 +160,8 @@ class EffectView : FrameLayout { private fun loadImg(resource: File) { "EffectView loadImg() ".doLog(mNeedLog) try { - val imageView = ImageView(context) - this@EffectView.addView(imageView) - imageView.setViewWH( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT, - false - ) - imageView.scaleType = ImageView.ScaleType.FIT_XY + val imageView = createImageView() + mImage = imageView Glide.with(this) .asBitmap() @@ -189,26 +190,8 @@ class EffectView : FrameLayout { imageView?.post { if (!imageView.isAttachedToWindow) return@post resource?.let { - if (hasAnimImg) { - val split: List = split(it) - if (split.isVerify()) { - val animationDrawable = AnimationDrawable() - for (i in split.indices) { - animationDrawable.addFrame(split[i], 200) - } - imageView.setImageDrawable(animationDrawable) - animationDrawable.isOneShot = false - animationDrawable.start() - } else { - imageView.setImageBitmap(it) - } - "EffectView loadImg() start".doLog(mNeedLog) - playCallBack(true) - } else { - "EffectView loadImg() start".doLog(mNeedLog) - playCallBack(true) - imageView.setImageBitmap(it) - } + mCallBack?.onCache(resource) + imgResourceLoad(imageView,resource) } } return true @@ -221,15 +204,48 @@ class EffectView : FrameLayout { } } + private fun createImageView() : ImageView { + val imageView = ImageView(context) + this@EffectView.addView(imageView) + imageView.setViewWH( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT, + false + ) + imageView.scaleType = ImageView.ScaleType.FIT_XY + return imageView + } + private fun imgResourceLoad(imageView: ImageView, resource: Bitmap) { + if (hasAnimImg) { + val split: List = split(resource) + if (split.isVerify()) { + val animationDrawable = AnimationDrawable() + for (i in split.indices) { + animationDrawable.addFrame(split[i], 200) + } + imageView.setImageDrawable(animationDrawable) + animationDrawable.isOneShot = false + animationDrawable.start() + } else { + imageView.setImageBitmap(resource) + } + "EffectView loadImg() start".doLog(mNeedLog) + playCallBack(true) + } else { + "EffectView loadImg() start".doLog(mNeedLog) + playCallBack(true) + imageView.setImageBitmap(resource) + } + } private fun loadMp4(resource: File) { "EffectView loadMp4() ".doLog(mNeedLog) try { val animView = AnimView(context) + mVap = animView + animView.setLoop(mPlayerCount) this@EffectView.addView(animView) animView.setViewWH(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT,false) -// AnimView.setLoop(Int.MAX_VALUE) -// AnimView.setScaleType(ScaleType.FIT_XY) animView.setAnimListener(object : IAnimListener { override fun onFailed(errorType: Int, errorMsg: String?) { playCallBack(false) @@ -326,6 +342,10 @@ class EffectView : FrameLayout { resources?.forEach { it?.bitmap?.recycle() } + + bitmapMap?.forEach { t, u -> + u?.recycle() + } } }) animView.startPlay(resource) @@ -375,23 +395,15 @@ class EffectView : FrameLayout { private fun loadSvga(resource: File) { "EffectView loadSvga() ".doLog(mNeedLog) try { - val svgaView = SVGAView(context) - this@EffectView.addView(svgaView) - svgaView.setViewWH(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT,false) - svgaView.scaleType = ImageView.ScaleType.FIT_XY + val svgaView = createSvgaView() + mSvga = svgaView val inputStream = BufferedInputStream(FileInputStream(resource.path)) shareParser().decodeFromInputStream( inputStream, resource.path, object : SVGAParser.ParseCompletion { override fun onComplete(videoItem: SVGAVideoEntity) { - svgaView.post { - if (!svgaView.isAttachedToWindow) return@post - svgaView.setImageDrawable(SVGADrawable(videoItem)) - svgaView.startAnimation() - playCallBack(true) - "EffectView loadSvga() true".doLog(mNeedLog) - } + playSvga(svgaView,videoItem) } override fun onError() { @@ -419,27 +431,8 @@ class EffectView : FrameLayout { return } - val svgaView = SVGAView(context) - this@EffectView.addView(svgaView) - svgaView.setViewWH(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT,false) - svgaView.scaleType = ImageView.ScaleType.FIT_XY - svgaView.callback = object : SVGACallback { - override fun onPause() { - "EffectView loadSvga() SVGACallback onPause()".doLog(mNeedLog) - } - - override fun onFinished() { - "EffectView loadSvga() SVGACallback onFinished()".doLog(mNeedLog) - } - - override fun onRepeat() { -// "EffectView loadSvga() SVGACallback onRepeat()".doLog(mNeedLog) - } - - override fun onStep(i: Int, v: Double) { - } - } - + val svgaView = createSvgaView() + mSvga = svgaView val dynamicEntity = SVGADynamicEntity() if (mTextMap?.isNotEmpty() == true) { @@ -498,14 +491,6 @@ class EffectView : FrameLayout { } } - private fun playCallBack(isSuccess: Boolean,type: Int? = -1) { - if (isSuccess) { - "EffectView playCallBack() 加载成功 url = $mResourceUrl".doLog(mNeedLog) - } else { - "EffectView playCallBack() 加载失败 url = $mResourceUrl".doLog(mNeedLog) - } - mCallBack?.onPlay(isSuccess,type) - } private fun split(bitmap: Bitmap?): List { "EffectView split() ".doLog(mNeedLog) @@ -580,24 +565,108 @@ class EffectView : FrameLayout { .submit() } - private fun playSvga(svgaView:SVGAView,videoItem: SVGAVideoEntity,dynamicEntity: SVGADynamicEntity) { - val drawable = SVGADrawable(videoItem, dynamicEntity) + + private fun createSvgaView() :SVGAView{ + val svgaView = SVGAView(context) + this@EffectView.addView(svgaView) + svgaView.setViewWH(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT,false) + svgaView.scaleType = ImageView.ScaleType.FIT_XY + svgaView.loops = mPlayerCount + svgaView.fillMode = SVGAImageView.FillMode.Forward + svgaView.callback = object : SVGACallback { + override fun onPause() { + "EffectView loadSvga() SVGACallback onPause()".doLog(mNeedLog) + } + + override fun onFinished() { + "EffectView loadSvga() SVGACallback onFinished()".doLog(mNeedLog) + } + + override fun onRepeat() { +// "EffectView loadSvga() SVGACallback onRepeat()".doLog(mNeedLog) + } + + override fun onStep(i: Int, v: Double) { + } + } + return svgaView + } + private fun playSvga(svgaView:SVGAView,videoItem: SVGAVideoEntity,dynamicEntity: SVGADynamicEntity?=null) { + val drawable = if (dynamicEntity != null) SVGADrawable(videoItem, dynamicEntity) else SVGADrawable(videoItem) + mCallBack?.onCache(drawable) svgaView.post { if (!svgaView.isAttachedToWindow) return@post svgaView.setImageDrawable(drawable) svgaView.stepToFrame(0, true) playCallBack(true) - "EffectView loadSvga() start".doLog(mNeedLog) + "EffectView playSvga() start".doLog(mNeedLog) } } + + public fun loadUrlForCache() { + + } + + public fun setTextView(textSize: Float) { mTextSize = textSize } - public interface CallBack{ - fun onPlay(isSuccess: Boolean,type: Int? = -1) + private fun playCallBack(isSuccess: Boolean,type: Int? = -1) { + if (isSuccess) { + "EffectView playCallBack() 加载成功 url = $mResourceUrl".doLog(mNeedLog) + } else { + "EffectView playCallBack() 加载失败 url = $mResourceUrl".doLog(mNeedLog) + } + mCallBack?.onPlay(isSuccess,type) } + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + "EffectView 被销毁了 $mResourceUrl".doLog() + + try { + mImage?.setImageBitmap(null) + mImage = null + + mSvga?.pauseAnimation() + mSvga?.stopAnimation() + mSvga?.clearAnimation() + mSvga?.clear() + mSvga = null + + mVap?.stopPlay() + mVap?.clearAnimation() + mVap=null + + removeAllViews() + } catch (e: Exception) { + "EffectView 被销毁了,回收资源异常 ${e.message}".doLog() + } + } + + public interface CallBack{ + fun onPlay(isSuccess: Boolean,type: Int? = -1) + fun onCache(resource:Any){}; + } + + + + class EffectLruCache(maxSize: Int){ + val mLruCache = LruCache(maxSize) + fun get(key: String): Any? { + return mLruCache.get(key) + } + + fun put(key: String, entity: Any) { + mLruCache.put(key, entity) + } + + fun clear() { + mLruCache.evictAll() + } + } + } \ No newline at end of file diff --git a/app/src/main/res/drawable-xhdpi/icon_dialog_mark_black_list.webp b/app/src/main/res/drawable-xhdpi/icon_dialog_mark_black_list.webp deleted file mode 100644 index dbd4752410cc87bb2c3cf3eeda3893c66db7f992..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1789 zcmV6pNLFQD%zr*Fu8c86ZfKY}%S<+qU^_ z`@e5%_P>y)d(W8#^pEKO1d!Rjcx||I{_@Sg?>8qq!&=-&8auPS<3C>d?-*I97MA4t z4;zm4q(wD%bHXN1;8w}edSwM)+YV)l_pB(2YJ@gf;Vmdo`DCS0G0VQn%CEtcz#(gh zfC-Un))EoJV$ZB8Vg^MYS=&b#;=f{z;Wxl~#9G6)+zM;HvQ&k&#}c7W{SaDgiv`?T zsK_Fg7I5Cn0O!0m3)!CIewE_QJ*&=Q)@N95<(Ob9$%3Y))+N~>!1*HyT!b8pngd3% zfN&|xB?2sLASF$@D-BkpS=p6l??Rf37isV%%{PntE6$rV-xFzGPNlinm1ciMnw73J zNJ*0kNE4tdSuP1$I+8GX_RQ8G66 zpvwcu=-`p#X}J!v5wo!S1$-*SH^$T~@5f1) z`am0CJivM2dJ6v8>H*RL=mFA^`=k4hh=XxP{QyH>!VE-u_62sj-;!_WoeMu9=?PNK*!vG=yWZA#DFX26 zm{x_&m^}g-cE2-%d=v`C^zx$OU_#7ez`u?8rE4SOLid|4@G+CFp4J;#v1)j)2mk>7 z`VrZrC~YnTt1)KM1s`nhCLlW-LBm*Y@f(hmYcR6}i_1O}vp9#or~bJUKZo*N*@Ffg z^8&)M2wlU~CZ*};?qFF{jmx9YSP@Hwa&%OR^tdLG{oPXTW)2KY6h>&_2lD7GyE*h zNG*|6WKo+uvc$`AhJFAJELZpo7A@MmaN*cnDC`g5ES>avaTrAOapUQHT;+?5?AMQ~ zNFobri8Zi%Z)7xv(UEaWI7m0ui2HR!VG{jU=jW{6+5ocBn@p{9ZLLGSpAGE$pblj` z5B{gSx`v&9LK(&Q_I)h8+eBYjL+)CPv;vjY4Wu+qxpH|R_EqeIJ42hTtm@wA0}$0@ z4G+{tLr4mne(s66`4zzE=-PM222VyPEW`dIl5_>qg;?dd-J7Bwv%MDUWT98M9?FdD z>SaR+lUAXBdTHjR4Go|ktz77Np*5G>`He?E+UU2xxhIt?e3R(vAyR0$%+XUgiNXAe zOP(Ok3OR+^q=Iru?Oth5v3*j_1@ni>R#_K3F5{xDbv z2xqtQi0gh?m=Q$$lQa*E^fxu_?60lJQ}%VfY+9%O^o`!is>%;hDg2JXUq}Km&O%_# z#=GgQ%~4U^c2-^26C@;4P?VMPdXpP@2DyP(<}?*{z+y!qC~Zd!9*b4sFS=PHH~UG= znjM%-zU*ywj{RL|*hc90yM;=eT*S=3lFhd{7TeMHI~#XfHr$1@aDE`>u=?*<2SV{$ zCU+0)gTjmf4eahq1-Gsv{=eHKcDcb2`{{6>zQW`DzYm=a-ZqByJL~-CgR=ovjWazX zk=j8Y=A=1|nlXgn`!S7{AOf+$jCg>Y)wcpRbWjonRW$bU-i&Gq$&WC<*gK~+%bNGU z&l=iq2#k?yJ;DEu_xXvZ^Z85BNxts9vO}&*K=4l|C(!Jjj3H~InE;lYp$kyJE>X0j z&H@_X*7)}Z6*pj{uO!_BXAj3BT>gwGKa+1_lu~^jv9=Y$C{5RoEpS(gs*n2ek{wFg`O3pkwF|9S3b-P)JW 0) { - CustomAttachment attachment = giftModel.giftQueue.remove(0); - if (attachment != null) - giftModel.parseChatRoomAttachment(attachment); + GiftModel giftModel = null; + try { + giftModel = mReference.get(); + if (giftModel == null) return; + super.handleMessage(msg); + if (giftModel.giftQueue.size() > 0) { + CustomAttachment attachment = giftModel.giftQueue.remove(0); + if (attachment != null) + giftModel.parseChatRoomAttachment(attachment); + } + } catch (Exception e) { + OtherExtKt.doLog(" 礼物消息异常 : "+e.getMessage()); } - if (giftModel.giftQueue.size() > 0) { + if (giftModel != null && !giftModel.giftQueue.isEmpty()) { sendEmptyMessageDelayed(0, 150); } } diff --git a/core/src/main/java/com/chwl/core/manager/IMNetEaseManager.java b/core/src/main/java/com/chwl/core/manager/IMNetEaseManager.java index 1cf51bff0..c0aaf0532 100644 --- a/core/src/main/java/com/chwl/core/manager/IMNetEaseManager.java +++ b/core/src/main/java/com/chwl/core/manager/IMNetEaseManager.java @@ -2944,7 +2944,7 @@ public final class IMNetEaseManager { carAttachment.effect = carInfo.getEffect(); carAttachment.viewUrl = carInfo.getViewUrl(); carAttachment.otherViewType = carInfo.getOtherViewType(); - + OtherExtKt.doLog(" 座驾 , 发送 座驾消息 播放动画"); ChatRoomMessage message = ChatRoomMessageBuilder.createChatRoomCustomMessage( String.valueOf(roomInfo.getRoomId()), carAttachment); e.onSuccess(message); diff --git a/library/src/main/java/com/chwl/library/widget/SVGAView.kt b/library/src/main/java/com/chwl/library/widget/SVGAView.kt index 9f7a5e769..7609911e3 100644 --- a/library/src/main/java/com/chwl/library/widget/SVGAView.kt +++ b/library/src/main/java/com/chwl/library/widget/SVGAView.kt @@ -267,7 +267,7 @@ class SVGAView : SVGAImageView, ILog { logD("SVGAView parseCompletion onComplete url:$url") if (resourceUrl != url) { return - } + } svgaCache?.put(resourceUrl ?: "", videoItem) this@SVGAView.post { this@SVGAView.setImageDrawable(SVGADrawable(videoItem))