Reduce number of invalidations in AsyncDrawable
This commit is contained in:
		
							parent
							
								
									2e7d0aa46b
								
							
						
					
					
						commit
						b55b1f0dcc
					
				| @ -4,6 +4,8 @@ | ||||
| * Fix SpannableBuilder `subSequence` method | ||||
| * Introduce Nougat check in `BulletListItemSpan` to position bullet (for bullets to be | ||||
| positioned correctly when nested inside other `LeadingMarginSpan`s)   | ||||
| * Reduced number of invalidations in AsyncDrawable when result is ready | ||||
| * AsyncDrawable#hasKnownDimentions -> AsyncDrawable#hasKnownDimensions typo fix | ||||
| 
 | ||||
| # 4.2.0 | ||||
| * `MarkwonEditor` to highlight markdown input whilst editing (new module: `markwon-editor`) | ||||
|  | ||||
| @ -4,7 +4,6 @@ | ||||
|     package="io.noties.markwon.app"> | ||||
| 
 | ||||
|     <uses-permission android:name="android.permission.INTERNET" /> | ||||
|     <uses-permission android:name="android.permission.ACCESS_ALL_DOWNLOADS" /> | ||||
| 
 | ||||
|     <application | ||||
|         android:name=".App" | ||||
|  | ||||
| @ -25,6 +25,7 @@ import io.noties.markwon.ext.tasklist.TaskListPlugin; | ||||
| import io.noties.markwon.html.HtmlPlugin; | ||||
| import io.noties.markwon.image.ImagesPlugin; | ||||
| import io.noties.markwon.image.file.FileSchemeHandler; | ||||
| import io.noties.markwon.image.gif.GifMediaDecoder; | ||||
| import io.noties.markwon.image.network.OkHttpNetworkSchemeHandler; | ||||
| import io.noties.markwon.syntax.Prism4jTheme; | ||||
| import io.noties.markwon.syntax.Prism4jThemeDarkula; | ||||
| @ -105,7 +106,8 @@ public class MarkdownRenderer { | ||||
|                                 // default-media-decoder is also added automatically | ||||
|                                 plugin | ||||
|                                         .addSchemeHandler(OkHttpNetworkSchemeHandler.create()) | ||||
|                                         .addSchemeHandler(FileSchemeHandler.createWithAssets(context.getAssets())); | ||||
|                                         .addSchemeHandler(FileSchemeHandler.createWithAssets(context.getAssets())) | ||||
|                                         .addMediaDecoder(GifMediaDecoder.create(false)); | ||||
|                             } | ||||
|                         })) | ||||
|                         .usePlugin(SyntaxHighlightPlugin.create(prism4j, prism4jTheme)) | ||||
|  | ||||
| @ -55,6 +55,7 @@ public class AsyncDrawable extends Drawable { | ||||
|     /** | ||||
|      * @since 4.0.0 | ||||
|      */ | ||||
|     @SuppressWarnings("WeakerAccess") | ||||
|     @Nullable | ||||
|     public ImageSize getImageSize() { | ||||
|         return imageSize; | ||||
| @ -63,20 +64,33 @@ public class AsyncDrawable extends Drawable { | ||||
|     /** | ||||
|      * @since 4.0.0 | ||||
|      */ | ||||
|     @SuppressWarnings("unused") | ||||
|     @NonNull | ||||
|     public ImageSizeResolver getImageSizeResolver() { | ||||
|         return imageSizeResolver; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @see #hasKnownDimensions() | ||||
|      * @since 4.0.0 | ||||
|      * @deprecated 4.2.1-SNAPSHOT | ||||
|      */ | ||||
|     @SuppressWarnings({"unused", "WeakerAccess"}) | ||||
|     @Deprecated | ||||
|     public boolean hasKnownDimentions() { | ||||
|         return canvasWidth > 0; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @see #hasKnownDimentions() | ||||
|      * @since 4.2.1-SNAPSHOT | ||||
|      */ | ||||
|     @SuppressWarnings({"unused", "WeakerAccess"}) | ||||
|     public boolean hasKnownDimensions() { | ||||
|         return canvasWidth > 0; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @see #hasKnownDimensions() | ||||
|      * @since 4.0.0 | ||||
|      */ | ||||
|     public int getLastKnownCanvasWidth() { | ||||
| @ -84,9 +98,10 @@ public class AsyncDrawable extends Drawable { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @see #hasKnownDimentions() | ||||
|      * @see #hasKnownDimensions() | ||||
|      * @since 4.0.0 | ||||
|      */ | ||||
|     @SuppressWarnings("WeakerAccess") | ||||
|     public float getLastKnowTextSize() { | ||||
|         return textSize; | ||||
|     } | ||||
| @ -95,6 +110,7 @@ public class AsyncDrawable extends Drawable { | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     @SuppressWarnings("WeakerAccess") | ||||
|     public boolean hasResult() { | ||||
|         return result != null; | ||||
|     } | ||||
| @ -104,10 +120,17 @@ public class AsyncDrawable extends Drawable { | ||||
|     } | ||||
| 
 | ||||
|     // yeah | ||||
|     public void setCallback2(@Nullable Callback callback) { | ||||
|     @SuppressWarnings("WeakerAccess") | ||||
|     public void setCallback2(@Nullable Callback cb) { | ||||
| 
 | ||||
|         this.callback = callback; | ||||
|         super.setCallback(callback); | ||||
|         // @since 4.2.1-SNAPSHOT | ||||
|         //  wrap callback so invalidation happens to this AsyncDrawable instance | ||||
|         //  and not for wrapped result/placeholder | ||||
|         this.callback = cb == null | ||||
|                 ? null | ||||
|                 : new WrappedCallback(cb); | ||||
| 
 | ||||
|         super.setCallback(cb); | ||||
| 
 | ||||
|         // if not null -> means we are attached | ||||
|         if (callback != null) { | ||||
| @ -138,6 +161,7 @@ public class AsyncDrawable extends Drawable { | ||||
|     /** | ||||
|      * @since 3.0.1 | ||||
|      */ | ||||
|     @SuppressWarnings("WeakerAccess") | ||||
|     protected void setPlaceholderResult(@NonNull Drawable placeholder) { | ||||
|         // okay, if placeholder has bounds -> use it, otherwise use original imageSize | ||||
| 
 | ||||
| @ -175,7 +199,6 @@ public class AsyncDrawable extends Drawable { | ||||
|         } | ||||
| 
 | ||||
|         this.result = result; | ||||
|         this.result.setCallback(callback); | ||||
| 
 | ||||
|         initBounds(); | ||||
|     } | ||||
| @ -210,6 +233,12 @@ public class AsyncDrawable extends Drawable { | ||||
| 
 | ||||
|         final Rect bounds = resolveBounds(); | ||||
|         result.setBounds(bounds); | ||||
|         // @since 4.2.1-SNAPSHOT, we set callback after bounds are resolved | ||||
|         //  to reduce number of invalidations | ||||
|         result.setCallback(callback); | ||||
| 
 | ||||
|         // so, this method will check if there is previous bounds and call invalidate _BEFORE_ | ||||
|         //  applying new bounds. This is why it is important to have initial bounds empty. | ||||
|         setBounds(bounds); | ||||
| 
 | ||||
|         invalidateSelf(); | ||||
| @ -291,6 +320,7 @@ public class AsyncDrawable extends Drawable { | ||||
|         return imageSizeResolver.resolveImageSize(this); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     @Override | ||||
|     public String toString() { | ||||
|         return "AsyncDrawable{" + | ||||
| @ -302,4 +332,30 @@ public class AsyncDrawable extends Drawable { | ||||
|                 ", waitingForDimensions=" + waitingForDimensions + | ||||
|                 '}'; | ||||
|     } | ||||
| 
 | ||||
|     // @since 4.2.1-SNAPSHOT | ||||
|     //  Wrapped callback to trigger invalidation for this AsyncDrawable instance (and not result/placeholder) | ||||
|     private class WrappedCallback implements Callback { | ||||
| 
 | ||||
|         private final Callback callback; | ||||
| 
 | ||||
|         WrappedCallback(@NonNull Callback callback) { | ||||
|             this.callback = callback; | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public void invalidateDrawable(@NonNull Drawable who) { | ||||
|             callback.invalidateDrawable(AsyncDrawable.this); | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) { | ||||
|             callback.scheduleDrawable(AsyncDrawable.this, what, when); | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) { | ||||
|             callback.unscheduleDrawable(AsyncDrawable.this, what); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -42,11 +42,9 @@ public class AsyncDrawableSpan extends ReplacementSpan { | ||||
|         this.alignment = alignment; | ||||
|         this.replacementTextIsLink = replacementTextIsLink; | ||||
| 
 | ||||
|         // additionally set intrinsic bounds if empty | ||||
|         final Rect rect = drawable.getBounds(); | ||||
|         if (rect.isEmpty()) { | ||||
|             drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); | ||||
|         } | ||||
|         // @since 4.2.1-SNAPSHOT we do not set intrinsic bounds | ||||
|         //  at this point they will always be 0,0-1,1, but this | ||||
|         //  will trigger another invalidation when we will have bounds | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Dimitry Ivanov
						Dimitry Ivanov