diff --git a/DanmakuFlameMaster/src/main/java/master/flame/danmaku/controller/CacheManagingDrawTask.java b/DanmakuFlameMaster/src/main/java/master/flame/danmaku/controller/CacheManagingDrawTask.java index b4309f99..bdbc20e8 100644 --- a/DanmakuFlameMaster/src/main/java/master/flame/danmaku/controller/CacheManagingDrawTask.java +++ b/DanmakuFlameMaster/src/main/java/master/flame/danmaku/controller/CacheManagingDrawTask.java @@ -319,6 +319,9 @@ protected void entryRemoved(boolean evicted, BaseDanmaku oldValue, BaseDanmaku n if (oldValue.cache != null) { IDrawingCache cache = oldValue.cache; long releasedSize = clearCache(oldValue); + if (oldValue.isTimeOut()) { + mContext.getDisplayer().getCacheStuffer().releaseResource(oldValue); + } if (releasedSize <= 0) return; mRealSize -= releasedSize; mCachePool.release((DrawingCache) cache); diff --git a/DanmakuFlameMaster/src/main/java/master/flame/danmaku/danmaku/model/android/BaseCacheStuffer.java b/DanmakuFlameMaster/src/main/java/master/flame/danmaku/danmaku/model/android/BaseCacheStuffer.java index b5295f67..004d6182 100644 --- a/DanmakuFlameMaster/src/main/java/master/flame/danmaku/danmaku/model/android/BaseCacheStuffer.java +++ b/DanmakuFlameMaster/src/main/java/master/flame/danmaku/danmaku/model/android/BaseCacheStuffer.java @@ -11,17 +11,19 @@ */ public abstract class BaseCacheStuffer { - public static abstract class Callback { + public static abstract class Proxy { /** * 在弹幕显示前使用新的text,使用新的text * @param danmaku * @param fromWorkerThread 是否在工作(非UI)线程,在true的情况下可以做一些耗时操作(例如更新Span的drawblae或者其他IO操作) * @return 如果不需重置,直接返回danmaku.text */ - public abstract void onPrepareDrawing(BaseDanmaku danmaku, boolean fromWorkerThread); + public abstract void prepareDrawing(BaseDanmaku danmaku, boolean fromWorkerThread); + + public abstract void releaseResource(BaseDanmaku danmaku); } - protected Callback mCallback; + protected Proxy mProxy; /** * set paintWidth, paintHeight to danmaku @@ -71,8 +73,14 @@ public void clearCache(BaseDanmaku danmaku) { } - public void setAdapter(Callback adapter) { - mCallback = adapter; + public void setProxy(Proxy adapter) { + mProxy = adapter; + } + + public void releaseResource(BaseDanmaku danmaku) { + if (mProxy != null) { + mProxy.releaseResource(danmaku); + } } } diff --git a/DanmakuFlameMaster/src/main/java/master/flame/danmaku/danmaku/model/android/DanmakuContext.java b/DanmakuFlameMaster/src/main/java/master/flame/danmaku/danmaku/model/android/DanmakuContext.java index 4202bc6a..a13ccfb5 100644 --- a/DanmakuFlameMaster/src/main/java/master/flame/danmaku/danmaku/model/android/DanmakuContext.java +++ b/DanmakuFlameMaster/src/main/java/master/flame/danmaku/danmaku/model/android/DanmakuContext.java @@ -583,10 +583,10 @@ public boolean isPreventOverlappingEnabled() { * @param cacheStuffer * @param cacheStufferAdapter */ - public DanmakuContext setCacheStuffer(BaseCacheStuffer cacheStuffer, BaseCacheStuffer.Callback cacheStufferAdapter) { + public DanmakuContext setCacheStuffer(BaseCacheStuffer cacheStuffer, BaseCacheStuffer.Proxy cacheStufferAdapter) { this.mCacheStuffer = cacheStuffer; if (this.mCacheStuffer != null) { - this.mCacheStuffer.setAdapter(cacheStufferAdapter); + this.mCacheStuffer.setProxy(cacheStufferAdapter); mDisplayer.setCacheStuffer(this.mCacheStuffer); } return this; diff --git a/DanmakuFlameMaster/src/main/java/master/flame/danmaku/danmaku/model/android/SimpleTextCacheStuffer.java b/DanmakuFlameMaster/src/main/java/master/flame/danmaku/danmaku/model/android/SimpleTextCacheStuffer.java index 11d56a97..bc31a357 100644 --- a/DanmakuFlameMaster/src/main/java/master/flame/danmaku/danmaku/model/android/SimpleTextCacheStuffer.java +++ b/DanmakuFlameMaster/src/main/java/master/flame/danmaku/danmaku/model/android/SimpleTextCacheStuffer.java @@ -29,8 +29,8 @@ protected Float getCacheHeight(BaseDanmaku danmaku, Paint paint) { @Override public void measure(BaseDanmaku danmaku, TextPaint paint, boolean fromWorkerThread) { - if (mCallback != null) { - mCallback.onPrepareDrawing(danmaku, fromWorkerThread); + if (mProxy != null) { + mProxy.prepareDrawing(danmaku, fromWorkerThread); } float w = 0; Float textHeight = 0f; diff --git a/DanmakuFlameMaster/src/main/java/master/flame/danmaku/danmaku/model/android/SpannedCacheStuffer.java b/DanmakuFlameMaster/src/main/java/master/flame/danmaku/danmaku/model/android/SpannedCacheStuffer.java index b0947eea..e802a31f 100644 --- a/DanmakuFlameMaster/src/main/java/master/flame/danmaku/danmaku/model/android/SpannedCacheStuffer.java +++ b/DanmakuFlameMaster/src/main/java/master/flame/danmaku/danmaku/model/android/SpannedCacheStuffer.java @@ -23,10 +23,10 @@ public class SpannedCacheStuffer extends SimpleTextCacheStuffer { @Override public void measure(BaseDanmaku danmaku, TextPaint paint, boolean fromWorkerThread) { if (danmaku.text instanceof Spanned) { - if (mCallback != null) { - mCallback.onPrepareDrawing(danmaku, fromWorkerThread); + if (mProxy != null) { + mProxy.prepareDrawing(danmaku, fromWorkerThread); } - CharSequence text = createNewSpan(danmaku, danmaku.text); + CharSequence text = danmaku.text; if (text != null) { StaticLayout staticLayout = new StaticLayout(text, paint, (int) StaticLayout.getDesiredWidth(danmaku.text, paint), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, true); danmaku.paintWidth = staticLayout.getWidth(); @@ -59,10 +59,10 @@ public void drawText(BaseDanmaku danmaku, String lineText, Canvas canvas, float if (requestInvalidate || staticLayout == null) { if (requestInvalidate) { danmaku.requestFlags &= ~BaseDanmaku.FLAG_REQUEST_INVALIDATE; - } else if (mCallback != null) { - mCallback.onPrepareDrawing(danmaku, fromWorkerThread); + } else if (mProxy != null) { + mProxy.prepareDrawing(danmaku, fromWorkerThread); } - CharSequence text = createNewSpan(danmaku, danmaku.text); + CharSequence text = danmaku.text; if (text != null) { if (requestRemeasure) { staticLayout = new StaticLayout(text, paint, (int) StaticLayout.getDesiredWidth(danmaku.text, paint), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, true); @@ -103,20 +103,9 @@ public void clearCache(BaseDanmaku danmaku) { } } - private CharSequence createNewSpan(BaseDanmaku danmaku, CharSequence text) { - if (text instanceof SpannableStringBuilder) { - text = new SpannableStringBuilder(text); - } else if (text instanceof Spannable) { - text = Spannable.Factory.getInstance().newSpannable(text); - } else if (text instanceof SpannedString) { - text = new SpannedString(text); - } else { - if (text != danmaku.text) { - DanmakuUtils.fillText(danmaku, text); - } - danmaku.obj = null; - return null; - } - return text; + @Override + public void releaseResource(BaseDanmaku danmaku) { + clearCache(danmaku); + super.releaseResource(danmaku); } } diff --git a/Sample/src/main/java/com/sample/MainActivity.java b/Sample/src/main/java/com/sample/MainActivity.java index c81752fc..7972bfea 100644 --- a/Sample/src/main/java/com/sample/MainActivity.java +++ b/Sample/src/main/java/com/sample/MainActivity.java @@ -77,12 +77,12 @@ public class MainActivity extends Activity implements View.OnClickListener { private Button mBtnSendDanmakus; private DanmakuContext mContext; - private BaseCacheStuffer.Callback mCacheStufferAdapter = new BaseCacheStuffer.Callback() { + private BaseCacheStuffer.Proxy mCacheStufferAdapter = new BaseCacheStuffer.Proxy() { private Drawable mDrawable; @Override - public void onPrepareDrawing(final BaseDanmaku danmaku, boolean fromWorkerThread) { + public void prepareDrawing(final BaseDanmaku danmaku, boolean fromWorkerThread) { if (danmaku.text instanceof Spanned) { // 根据你的条件检查是否需要需要更新弹幕 // FIXME 这里只是简单启个线程来加载远程url图片,请使用你自己的异步线程池,最好加上你的缓存池 new Thread() { @@ -119,6 +119,11 @@ public void run() { }.start(); } } + + @Override + public void releaseResource(BaseDanmaku danmaku) { + // TODO 重要:清理含有ImageSpan的text中的一些占用内存的资源 例如drawable + } }; /**