Repository: dotnet/maui
File: src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/glide/MauiCustomTarget.java (Java)

Code before:
        }

        return false;
    }

    /**
     * Gets the Activity from a Context.
     * @param context The context to get the activity from
     * @return The activity if found, null otherwise
     */
    private static Activity getActivity(Context context) {
        if (context == null) {
            return null;
        }

        if (context instanceof Activity) {
            return (Activity) context;
        }

        if (context instanceof ContextWrapper) {
            Context baseContext = ((ContextWrapper) context).getBaseContext();
            return getActivity(baseContext);
        }

        return null;
    }

    private final Context context;
    private final ImageLoaderCallback callback;
    private final String resourceLogIdentifier;
    private boolean completed;

    public MauiCustomTarget(Context context, ImageLoaderCallback callback, Object model) {
        this.completed = false;
        this.context = context;
        this.callback = callback;

        if (logger.isVerboseLoggable && model != null) {
            this.resourceLogIdentifier = model.toString();
        } else {
            this.resourceLogIdentifier = null;
        }
    }

    public void load(RequestBuilder<Drawable> builder) {
        builder.into(this);
    }

    @Override
    public void onLoadFailed(@Nullable Drawable errorDrawable) {
        if (completed)

Review comment (suggestion):
This code is duplcated, can it call `PlatformInterop` version instead?

Make the methods above "internal" so they can be called within the same package.

Code after:

        callback.onComplete(true, resource, this::clear);
    }

    @Override
    public void onLoadCleared(@Nullable Drawable placeholder) {
        if (logger.isVerboseLoggable) logger.v("onLoadCleared: " + resourceLogIdentifier);
    }

    private void post(Runnable runnable) {
        Looper looper = Looper.getMainLooper();
        if (looper.isCurrentThread()) {
            runnable.run();
            return;
        }

        Handler handler = new Handler(looper);
        handler.post(runnable);
    }

    private static boolean isContextDestroyed(Context context) {
        Activity activity = getActivity(context);
        if (activity != null) {
            if (activity.isFinishing() || activity.isDestroyed()) {
                return true;
            }
        }
        return false;
    }

    private static Activity getActivity(Context context) {
        if (context == null) {
            return null;
        }
        if (context instanceof Activity) {
            return (Activity) context;
        }
        if (context instanceof ContextWrapper) {
            Context baseContext = ((ContextWrapper) context).getBaseContext();
            return getActivity(baseContext);
        }
        return null;
    }

    private void clear() {
        // TODO: it looks like no one is really disposing the result on C# side
        // we must fix it there to release the Glide cache entry properly
        post(() -> {
            if (isContextDestroyed(context)) {
                if (logger.isVerboseLoggable) {
                    logger.v("clear() skipped - context destroyed: " + resourceLogIdentifier);