Loading graphics/java/android/graphics/drawable/AnimatedImageDrawable.java +10 −2 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.io.InputStream; import java.lang.ref.WeakReference; import java.util.ArrayList; /** Loading Loading @@ -494,7 +495,7 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { if (mAnimationCallbacks == null) { mAnimationCallbacks = new ArrayList<Animatable2.AnimationCallback>(); nSetOnAnimationEndListener(mState.mNativePtr, this); nSetOnAnimationEndListener(mState.mNativePtr, new WeakReference<>(this)); } if (!mAnimationCallbacks.contains(callback)) { Loading Loading @@ -562,6 +563,13 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { * callback, so no need to post. */ @SuppressWarnings("unused") private static void callOnAnimationEnd(WeakReference<AnimatedImageDrawable> weakDrawable) { AnimatedImageDrawable drawable = weakDrawable.get(); if (drawable != null) { drawable.onAnimationEnd(); } } private void onAnimationEnd() { if (mAnimationCallbacks != null) { for (Animatable2.AnimationCallback callback : mAnimationCallbacks) { Loading Loading @@ -603,7 +611,7 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { private static native void nSetRepeatCount(long nativePtr, int repeatCount); // Pass the drawable down to native so it can call onAnimationEnd. private static native void nSetOnAnimationEndListener(long nativePtr, @Nullable AnimatedImageDrawable drawable); @Nullable WeakReference<AnimatedImageDrawable> drawable); @FastNative private static native long nNativeByteSize(long nativePtr); @FastNative Loading libs/hwui/jni/AnimatedImageDrawable.cpp +29 −26 Original line number Diff line number Diff line Loading @@ -30,7 +30,8 @@ using namespace android; static jmethodID gAnimatedImageDrawable_onAnimationEndMethodID; static jclass gAnimatedImageDrawableClass; static jmethodID gAnimatedImageDrawable_callOnAnimationEndMethodID; // Note: jpostProcess holds a handle to the ImageDecoder. static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/, Loading Loading @@ -178,26 +179,23 @@ class InvokeListener : public MessageHandler { public: InvokeListener(JNIEnv* env, jobject javaObject) { LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&mJvm) != JNI_OK); // Hold a weak reference to break a cycle that would prevent GC. mWeakRef = env->NewWeakGlobalRef(javaObject); mCallbackRef = env->NewGlobalRef(javaObject); } ~InvokeListener() override { auto* env = requireEnv(mJvm); env->DeleteWeakGlobalRef(mWeakRef); env->DeleteGlobalRef(mCallbackRef); } virtual void handleMessage(const Message&) override { auto* env = get_env_or_die(mJvm); jobject localRef = env->NewLocalRef(mWeakRef); if (localRef) { env->CallVoidMethod(localRef, gAnimatedImageDrawable_onAnimationEndMethodID); } env->CallStaticVoidMethod(gAnimatedImageDrawableClass, gAnimatedImageDrawable_callOnAnimationEndMethodID, mCallbackRef); } private: JavaVM* mJvm; jweak mWeakRef; jobject mCallbackRef; }; class JniAnimationEndListener : public OnAnimationEndListener { Loading Loading @@ -253,7 +251,8 @@ static void AnimatedImageDrawable_nSetBounds(JNIEnv* env, jobject /*clazz*/, jlo } static const JNINativeMethod gAnimatedImageDrawableMethods[] = { { "nCreate", "(JLandroid/graphics/ImageDecoder;IIJZLandroid/graphics/Rect;)J",(void*) AnimatedImageDrawable_nCreate }, {"nCreate", "(JLandroid/graphics/ImageDecoder;IIJZLandroid/graphics/Rect;)J", (void*)AnimatedImageDrawable_nCreate}, {"nGetNativeFinalizer", "()J", (void*)AnimatedImageDrawable_nGetNativeFinalizer}, {"nDraw", "(JJ)J", (void*)AnimatedImageDrawable_nDraw}, {"nSetAlpha", "(JI)V", (void*)AnimatedImageDrawable_nSetAlpha}, Loading @@ -264,15 +263,19 @@ static const JNINativeMethod gAnimatedImageDrawableMethods[] = { {"nStop", "(J)Z", (void*)AnimatedImageDrawable_nStop}, {"nGetRepeatCount", "(J)I", (void*)AnimatedImageDrawable_nGetRepeatCount}, {"nSetRepeatCount", "(JI)V", (void*)AnimatedImageDrawable_nSetRepeatCount}, { "nSetOnAnimationEndListener", "(JLandroid/graphics/drawable/AnimatedImageDrawable;)V", (void*) AnimatedImageDrawable_nSetOnAnimationEndListener }, {"nSetOnAnimationEndListener", "(JLjava/lang/ref/WeakReference;)V", (void*)AnimatedImageDrawable_nSetOnAnimationEndListener}, {"nNativeByteSize", "(J)J", (void*)AnimatedImageDrawable_nNativeByteSize}, {"nSetMirrored", "(JZ)V", (void*)AnimatedImageDrawable_nSetMirrored}, {"nSetBounds", "(JLandroid/graphics/Rect;)V", (void*)AnimatedImageDrawable_nSetBounds}, }; int register_android_graphics_drawable_AnimatedImageDrawable(JNIEnv* env) { jclass animatedImageDrawable_class = FindClassOrDie(env, "android/graphics/drawable/AnimatedImageDrawable"); gAnimatedImageDrawable_onAnimationEndMethodID = GetMethodIDOrDie(env, animatedImageDrawable_class, "onAnimationEnd", "()V"); gAnimatedImageDrawableClass = reinterpret_cast<jclass>(env->NewGlobalRef( FindClassOrDie(env, "android/graphics/drawable/AnimatedImageDrawable"))); gAnimatedImageDrawable_callOnAnimationEndMethodID = GetStaticMethodIDOrDie(env, gAnimatedImageDrawableClass, "callOnAnimationEnd", "(Ljava/lang/ref/WeakReference;)V"); return android::RegisterMethodsOrDie(env, "android/graphics/drawable/AnimatedImageDrawable", gAnimatedImageDrawableMethods, NELEM(gAnimatedImageDrawableMethods)); Loading Loading
graphics/java/android/graphics/drawable/AnimatedImageDrawable.java +10 −2 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.io.InputStream; import java.lang.ref.WeakReference; import java.util.ArrayList; /** Loading Loading @@ -494,7 +495,7 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { if (mAnimationCallbacks == null) { mAnimationCallbacks = new ArrayList<Animatable2.AnimationCallback>(); nSetOnAnimationEndListener(mState.mNativePtr, this); nSetOnAnimationEndListener(mState.mNativePtr, new WeakReference<>(this)); } if (!mAnimationCallbacks.contains(callback)) { Loading Loading @@ -562,6 +563,13 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { * callback, so no need to post. */ @SuppressWarnings("unused") private static void callOnAnimationEnd(WeakReference<AnimatedImageDrawable> weakDrawable) { AnimatedImageDrawable drawable = weakDrawable.get(); if (drawable != null) { drawable.onAnimationEnd(); } } private void onAnimationEnd() { if (mAnimationCallbacks != null) { for (Animatable2.AnimationCallback callback : mAnimationCallbacks) { Loading Loading @@ -603,7 +611,7 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { private static native void nSetRepeatCount(long nativePtr, int repeatCount); // Pass the drawable down to native so it can call onAnimationEnd. private static native void nSetOnAnimationEndListener(long nativePtr, @Nullable AnimatedImageDrawable drawable); @Nullable WeakReference<AnimatedImageDrawable> drawable); @FastNative private static native long nNativeByteSize(long nativePtr); @FastNative Loading
libs/hwui/jni/AnimatedImageDrawable.cpp +29 −26 Original line number Diff line number Diff line Loading @@ -30,7 +30,8 @@ using namespace android; static jmethodID gAnimatedImageDrawable_onAnimationEndMethodID; static jclass gAnimatedImageDrawableClass; static jmethodID gAnimatedImageDrawable_callOnAnimationEndMethodID; // Note: jpostProcess holds a handle to the ImageDecoder. static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/, Loading Loading @@ -178,26 +179,23 @@ class InvokeListener : public MessageHandler { public: InvokeListener(JNIEnv* env, jobject javaObject) { LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&mJvm) != JNI_OK); // Hold a weak reference to break a cycle that would prevent GC. mWeakRef = env->NewWeakGlobalRef(javaObject); mCallbackRef = env->NewGlobalRef(javaObject); } ~InvokeListener() override { auto* env = requireEnv(mJvm); env->DeleteWeakGlobalRef(mWeakRef); env->DeleteGlobalRef(mCallbackRef); } virtual void handleMessage(const Message&) override { auto* env = get_env_or_die(mJvm); jobject localRef = env->NewLocalRef(mWeakRef); if (localRef) { env->CallVoidMethod(localRef, gAnimatedImageDrawable_onAnimationEndMethodID); } env->CallStaticVoidMethod(gAnimatedImageDrawableClass, gAnimatedImageDrawable_callOnAnimationEndMethodID, mCallbackRef); } private: JavaVM* mJvm; jweak mWeakRef; jobject mCallbackRef; }; class JniAnimationEndListener : public OnAnimationEndListener { Loading Loading @@ -253,7 +251,8 @@ static void AnimatedImageDrawable_nSetBounds(JNIEnv* env, jobject /*clazz*/, jlo } static const JNINativeMethod gAnimatedImageDrawableMethods[] = { { "nCreate", "(JLandroid/graphics/ImageDecoder;IIJZLandroid/graphics/Rect;)J",(void*) AnimatedImageDrawable_nCreate }, {"nCreate", "(JLandroid/graphics/ImageDecoder;IIJZLandroid/graphics/Rect;)J", (void*)AnimatedImageDrawable_nCreate}, {"nGetNativeFinalizer", "()J", (void*)AnimatedImageDrawable_nGetNativeFinalizer}, {"nDraw", "(JJ)J", (void*)AnimatedImageDrawable_nDraw}, {"nSetAlpha", "(JI)V", (void*)AnimatedImageDrawable_nSetAlpha}, Loading @@ -264,15 +263,19 @@ static const JNINativeMethod gAnimatedImageDrawableMethods[] = { {"nStop", "(J)Z", (void*)AnimatedImageDrawable_nStop}, {"nGetRepeatCount", "(J)I", (void*)AnimatedImageDrawable_nGetRepeatCount}, {"nSetRepeatCount", "(JI)V", (void*)AnimatedImageDrawable_nSetRepeatCount}, { "nSetOnAnimationEndListener", "(JLandroid/graphics/drawable/AnimatedImageDrawable;)V", (void*) AnimatedImageDrawable_nSetOnAnimationEndListener }, {"nSetOnAnimationEndListener", "(JLjava/lang/ref/WeakReference;)V", (void*)AnimatedImageDrawable_nSetOnAnimationEndListener}, {"nNativeByteSize", "(J)J", (void*)AnimatedImageDrawable_nNativeByteSize}, {"nSetMirrored", "(JZ)V", (void*)AnimatedImageDrawable_nSetMirrored}, {"nSetBounds", "(JLandroid/graphics/Rect;)V", (void*)AnimatedImageDrawable_nSetBounds}, }; int register_android_graphics_drawable_AnimatedImageDrawable(JNIEnv* env) { jclass animatedImageDrawable_class = FindClassOrDie(env, "android/graphics/drawable/AnimatedImageDrawable"); gAnimatedImageDrawable_onAnimationEndMethodID = GetMethodIDOrDie(env, animatedImageDrawable_class, "onAnimationEnd", "()V"); gAnimatedImageDrawableClass = reinterpret_cast<jclass>(env->NewGlobalRef( FindClassOrDie(env, "android/graphics/drawable/AnimatedImageDrawable"))); gAnimatedImageDrawable_callOnAnimationEndMethodID = GetStaticMethodIDOrDie(env, gAnimatedImageDrawableClass, "callOnAnimationEnd", "(Ljava/lang/ref/WeakReference;)V"); return android::RegisterMethodsOrDie(env, "android/graphics/drawable/AnimatedImageDrawable", gAnimatedImageDrawableMethods, NELEM(gAnimatedImageDrawableMethods)); Loading