From 15a11ceafd954cb6021fd4b61cd5995df0a4ab91 Mon Sep 17 00:00:00 2001 From: chaihua1 Date: Fri, 25 Aug 2023 20:18:08 +0800 Subject: [PATCH] =?UTF-8?q?[#605]=E4=BF=AE=E5=A4=8DAndroid=2013=E9=94=81?= =?UTF-8?q?=E5=B1=8F=E5=8A=A8=E7=94=BB=E5=A4=84=E7=90=86=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E7=9A=84=E5=B4=A9=E6=BA=83=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: chaihua1 --- .../hapjs/component/animation/Animation.java | 7 +++ .../component/animation/CSSAnimatorSet.java | 10 +++ .../component/feature/AnimationFeature.java | 63 ++++++++++++++++++- 3 files changed, 79 insertions(+), 1 deletion(-) diff --git a/core/runtime/android/runtime/src/main/java/org/hapjs/component/animation/Animation.java b/core/runtime/android/runtime/src/main/java/org/hapjs/component/animation/Animation.java index 97ae900f..0d17dbc5 100755 --- a/core/runtime/android/runtime/src/main/java/org/hapjs/component/animation/Animation.java +++ b/core/runtime/android/runtime/src/main/java/org/hapjs/component/animation/Animation.java @@ -7,6 +7,7 @@ import java.util.HashMap; import java.util.Map; + import org.hapjs.component.Component; public class Animation { @@ -101,6 +102,12 @@ public void pause() { } } + public void resume() { + if (mAnimatorSet != null) { + mAnimatorSet.resume(); + } + } + public void finish() { if (mAnimatorSet != null) { mAnimatorSet.finish(); diff --git a/core/runtime/android/runtime/src/main/java/org/hapjs/component/animation/CSSAnimatorSet.java b/core/runtime/android/runtime/src/main/java/org/hapjs/component/animation/CSSAnimatorSet.java index 33f5e924..66116a8d 100755 --- a/core/runtime/android/runtime/src/main/java/org/hapjs/component/animation/CSSAnimatorSet.java +++ b/core/runtime/android/runtime/src/main/java/org/hapjs/component/animation/CSSAnimatorSet.java @@ -30,9 +30,11 @@ import android.view.View; import android.view.animation.Interpolator; import android.view.animation.LinearInterpolator; + import java.lang.ref.WeakReference; import java.util.Collection; import java.util.Objects; + import org.hapjs.common.utils.ColorUtil; import org.hapjs.component.Component; import org.hapjs.component.bridge.SimpleActivityStateListener; @@ -228,6 +230,10 @@ public void setRepeatCount(int repeatCount) { } } + public int getRepeatCount() { + return mRepeatCount; + } + public void start() { if (mComponent == null) { return; @@ -264,6 +270,10 @@ public void pause() { mWrapped.pause(); } + public void resume() { + mWrapped.resume(); + } + public void reverse() { for (Animator animator : mWrapped.getChildAnimations()) { animator.end(); diff --git a/core/runtime/android/runtime/src/main/java/org/hapjs/component/feature/AnimationFeature.java b/core/runtime/android/runtime/src/main/java/org/hapjs/component/feature/AnimationFeature.java index 4b0b4ac7..d99bd0b1 100755 --- a/core/runtime/android/runtime/src/main/java/org/hapjs/component/feature/AnimationFeature.java +++ b/core/runtime/android/runtime/src/main/java/org/hapjs/component/feature/AnimationFeature.java @@ -7,12 +7,17 @@ import android.app.Activity; import android.util.Log; + import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; + import org.hapjs.bridge.CallbackContext; import org.hapjs.bridge.CallbackContextHolder; import org.hapjs.bridge.CallbackHybridFeature; import org.hapjs.bridge.FeatureExtension; +import org.hapjs.bridge.HybridManager; +import org.hapjs.bridge.LifecycleListener; import org.hapjs.bridge.Request; import org.hapjs.bridge.Response; import org.hapjs.bridge.annotation.ActionAnnotation; @@ -82,7 +87,42 @@ public class AnimationFeature extends CallbackHybridFeature { protected static final String EVENT_ON_ANIMATION_FINISH = "onfinish"; private static final String TAG = "AnimationFeature"; private static final String CONNECTOR = "-"; - private Map mAnimations = new ConcurrentHashMap<>(); + private final Map mAnimations = new ConcurrentHashMap<>(); + private final Map mPausingAnimations = new ConcurrentHashMap<>(); + private final Object mLock = new Object(); + private HybridManager mHybridManager; + private final LifecycleListener mLifecycleListener = new LifecycleListener() { + @Override + public void onResume() { + super.onResume(); + synchronized (mLock) { + Set> entries = mPausingAnimations.entrySet(); + for (Map.Entry entry : entries) { + entry.getValue().resume(); + } + mPausingAnimations.clear(); + } + } + + @Override + public void onPause() { + super.onPause(); + synchronized (mLock) { + Set> entries = mAnimations.entrySet(); + for (Map.Entry entry : entries) { + Animation animation = entry.getValue(); + //页面 onPause 时,要暂停所有 infinity 的动画,否则会在 Android 13 的设备上崩溃 + if (animation.getAnimatorSet() != null + && Integer.MAX_VALUE == animation.getAnimatorSet().getRepeatCount()) { + if (animation.getPlayState().equals("running")) { + mPausingAnimations.put(entry.getKey(), entry.getValue()); + animation.pause(); + } + } + } + } + } + }; @Override public String getName() { @@ -98,6 +138,10 @@ protected Response invokeInner(final Request request) throws Exception { Activity activity = request.getNativeInterface().getActivity(); switch (request.getAction()) { case ACTION_ENABLE: + if (mHybridManager == null) { + mHybridManager = request.getView().getHybridManager(); + setLifecycleListener(); + } enable(request, compId, animId); break; case ACTION_PLAY: @@ -114,6 +158,9 @@ public void run() { new Runnable() { @Override public void run() { + synchronized (mLock) { + mPausingAnimations.remove(key); + } pause(key); } }); @@ -177,6 +224,12 @@ public void run() { return Response.SUCCESS; } + private void setLifecycleListener() { + if (mHybridManager != null) { + mHybridManager.addLifecycleListener(mLifecycleListener); + } + } + private void enable(Request request, String compId, String animId) { int ref = Integer.parseInt(compId); RootView rootView = request.getNativeInterface().getRootView(); @@ -405,6 +458,14 @@ public boolean isBuiltInExtension() { return true; } + @Override + public void dispose(boolean force) { + super.dispose(force); + if (force && mHybridManager != null) { + mHybridManager.removeLifecycleListener(mLifecycleListener); + } + } + private class AnimationCallbackContext extends CallbackContext implements Animation.OnFinishListener, Animation.OnCancelListener {