diff --git a/README.md b/README.md
index 6835e2b086e36f0b7a695a64e01cc03dd013be02..914c5e1d3c3010966994a71fa4bbb0690280f4e2 100644
--- a/README.md
+++ b/README.md
@@ -55,5 +55,5 @@ where string is the url path to the json file to be loaded.
```
dependencies {
implementation fileTree(dir: 'libs', include: ['*.har'])
- implementation 'io.openharmony.tpc.thirdlib:lottie-ohos:1.0.7'
+ implementation 'io.openharmony.tpc.thirdlib:lottie-ohos:1.0.8'
}
\ No newline at end of file
diff --git a/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java b/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java
index 842a2c3a89374b8f53507b14311479911f7a1ed5..8fd3cb2fed2b2959dc7866d5f86857af4b9b0dba 100644
--- a/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java
+++ b/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java
@@ -1,7 +1,6 @@
package com.airbnb.lottie;
import com.airbnb.lottie.model.KeyPath;
-import com.airbnb.lottie.parser.moshi.JsonReader;
import com.airbnb.lottie.utils.ContextUtil;
import com.airbnb.lottie.utils.HMOSLogUtil;
import com.airbnb.lottie.value.SimpleLottieValueCallback;
@@ -1038,7 +1037,7 @@ public class LottieAnimationView extends Image implements Component.BindStateCha
//TODO : scaleType FitXY mode is not supported in HMOS
/**
- * Disable the extraScale mode in {@link #drawToCanvas(Canvas)} function when scaleType is FitXY. It doesn't affect the rendering with other scaleTypes.
+ * Disable the extraScale mode in {@link LottieDrawable#drawToCanvas(Canvas)} function when scaleType is FitXY. It doesn't affect the rendering with other scaleTypes.
*
*
When there are 2 animation layout side by side, the default extra scale mode might leave 1 pixel not drawn between 2 animation, and
* disabling the extraScale mode can fix this problem
@@ -1046,7 +1045,7 @@ public class LottieAnimationView extends Image implements Component.BindStateCha
* Attention: Disable the extra scale mode can downgrade the performance and may lead to larger memory footprint. Please only disable this
* mode when using animation with a reasonable dimension (smaller than screen size).
*
- * @see LottieDrawable#drawWithNewAspectRatio(Canvas)
+ * @see LottieDrawable drawWithNewAspectRatio(Canvas)
*/
/*public void disableExtraScaleModeInFitXY() {
lottieHMOSDrawable.disableExtraScaleModeInFitXY();
diff --git a/lottie/src/main/java/com/airbnb/lottie/utils/InvalidationHandler.java b/lottie/src/main/java/com/airbnb/lottie/utils/InvalidationHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..1a8c16f395c5749521068c142b41e6beceb78ff8
--- /dev/null
+++ b/lottie/src/main/java/com/airbnb/lottie/utils/InvalidationHandler.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.airbnb.lottie.utils;
+
+import ohos.eventhandler.EventHandler;
+import ohos.eventhandler.EventRunner;
+import ohos.eventhandler.InnerEvent;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * 功能描述
+ */
+class InvalidationHandler extends EventHandler {
+ static final int MSG_TYPE_INVALIDATION = -1;
+
+ private final WeakReference mLottieRef;
+
+ InvalidationHandler(final LottieValueAnimator gifDrawable) {
+ super(EventRunner.getMainEventRunner());
+ mLottieRef = new WeakReference<>(gifDrawable);
+ }
+
+ @Override
+ protected void processEvent(InnerEvent event) {
+ final LottieValueAnimator ltDrawable = mLottieRef.get();
+ if (ltDrawable == null) {
+ return;
+ }
+ if (event.eventId == MSG_TYPE_INVALIDATION) {
+ ltDrawable.doFrame(System.nanoTime());
+ }
+ }
+}
diff --git a/lottie/src/main/java/com/airbnb/lottie/utils/LottieDelayExecutor.java b/lottie/src/main/java/com/airbnb/lottie/utils/LottieDelayExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..20d8991ea5f77c64029879b6e4323c517a0b1094
--- /dev/null
+++ b/lottie/src/main/java/com/airbnb/lottie/utils/LottieDelayExecutor.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.airbnb.lottie.utils;
+
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+
+final class LottieDelayExecutor extends ScheduledThreadPoolExecutor {
+ private static final int CORE_POOL_SIZE = 1;
+
+ private LottieDelayExecutor() {
+ super(CORE_POOL_SIZE, new DiscardPolicy());
+ }
+
+ // Lazy initialization via inner-class holder
+ private static final class InstanceHolder {
+ private static final LottieDelayExecutor INSTANCE = new LottieDelayExecutor();
+ }
+
+ static LottieDelayExecutor getInstance() {
+ return InstanceHolder.INSTANCE;
+ }
+}
diff --git a/lottie/src/main/java/com/airbnb/lottie/utils/LottieValueAnimator.java b/lottie/src/main/java/com/airbnb/lottie/utils/LottieValueAnimator.java
index 3884cf9859bed67e1a8b97ddf45a212820e79890..76e9526e8a23e45fe1f8b34e79048e737fdf3ed3 100644
--- a/lottie/src/main/java/com/airbnb/lottie/utils/LottieValueAnimator.java
+++ b/lottie/src/main/java/com/airbnb/lottie/utils/LottieValueAnimator.java
@@ -4,16 +4,20 @@ import com.airbnb.lottie.LottieComposition;
import ohos.agp.animation.AnimatorValue;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
/**
* This is a slightly modified {@link AnimatorValue} that allows us to update start and end values
* easily optimizing for the fact that we know that it's a value animator with 2 floats.
*/
-public class LottieValueAnimator extends BaseLottieAnimator implements InvocationHandler {
+public class LottieValueAnimator extends BaseLottieAnimator {
+ private static final long EXCEEDS_TIME_SINCE_FRAME = 280000000;
+
+ private static final long AVERAGE_TIME_SINCE_FRAME = 180000000;
+
+ private static final long FRAME_TIME_INTERVAL = 16L;
private float speed = 1f;
@@ -33,28 +37,15 @@ public class LottieValueAnimator extends BaseLottieAnimator implements Invocatio
protected boolean running = false;
- private Class> choreographerClass;
-
- private Class> frameCallbackClass;
-
- private Object callbackProxy;
-
- private Object choreographerObject;
-
public LottieValueAnimator() {
- try {
- choreographerClass = Class.forName("android.view.Choreographer");
- frameCallbackClass = Class.forName("android.view.Choreographer$FrameCallback");
- callbackProxy = Proxy.newProxyInstance(frameCallbackClass.getClass().getClassLoader(),
- new Class[]{frameCallbackClass}, this);
- Method getInstanceMethod = choreographerClass.getMethod("getInstance", (Class>[]) null);
- choreographerObject = getInstanceMethod.invoke(null);
- } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException |
- InvocationTargetException e) {
- e.printStackTrace();
- }
+ mInvalidationHandler = new InvalidationHandler(this);
}
+ private final RenderTask mRenderTask = new RenderTask(this);
+ final ScheduledThreadPoolExecutor mExecutor = LottieDelayExecutor.getInstance();
+ ScheduledFuture> mRenderTaskSchedule;
+ final InvalidationHandler mInvalidationHandler;
+
/**
* Returns a float representing the current value of the animation from 0 to 1
* regardless of the animation speed, direction, or min and max frames.
@@ -112,15 +103,6 @@ public class LottieValueAnimator extends BaseLottieAnimator implements Invocatio
return running;
}
- @Override
- public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
- if (objects != null && objects.length > 0) {
- long frameTimeNanos = (long) objects[0];
- this.doFrame(frameTimeNanos);
- }
- return null;
- }
-
public void doFrame(long frameTimeNanos) {
postFrameCallback();
if (composition == null || !isRunning()) {
@@ -128,6 +110,9 @@ public class LottieValueAnimator extends BaseLottieAnimator implements Invocatio
}
//HiTraceId traceid = L.beginSection("LottieValueAnimator#doFrame");
long timeSinceFrame = lastFrameTimeNs == 0 ? 0 : frameTimeNanos - lastFrameTimeNs;
+ if (timeSinceFrame > EXCEEDS_TIME_SINCE_FRAME) {
+ timeSinceFrame = AVERAGE_TIME_SINCE_FRAME;
+ }
float frameDuration = getFrameDurationNs();
float dFrames = timeSinceFrame / frameDuration;
@@ -319,13 +304,7 @@ public class LottieValueAnimator extends BaseLottieAnimator implements Invocatio
protected void postFrameCallback() {
if (isRunning()) {
removeFrameCallback(false);
- try {
- Method postFrameMethod = choreographerClass.getDeclaredMethod("postFrameCallback",
- new Class[]{frameCallbackClass});
- postFrameMethod.invoke(choreographerObject, new Object[]{callbackProxy});
- } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
- e.printStackTrace();
- }
+ mRenderTaskSchedule = mExecutor.schedule(mRenderTask, FRAME_TIME_INTERVAL, TimeUnit.MILLISECONDS);
}
}
@@ -336,13 +315,7 @@ public class LottieValueAnimator extends BaseLottieAnimator implements Invocatio
//MainThread
protected void removeFrameCallback(boolean stopRunning) {
- try {
- Method removeFrameMethod = choreographerClass.getDeclaredMethod("removeFrameCallback",
- new Class[]{frameCallbackClass});
- removeFrameMethod.invoke(choreographerObject, new Object[]{callbackProxy});
- } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
- e.printStackTrace();
- }
+ mExecutor.remove(mRenderTask);
if (stopRunning) {
running = false;
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/utils/RenderTask.java b/lottie/src/main/java/com/airbnb/lottie/utils/RenderTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..8e3476afda7feb74795ecb94b2e5ac26d95485b4
--- /dev/null
+++ b/lottie/src/main/java/com/airbnb/lottie/utils/RenderTask.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.airbnb.lottie.utils;
+
+
+class RenderTask extends SafeRunnable {
+
+ RenderTask(LottieValueAnimator ltAnimator) {
+ super(ltAnimator);
+ }
+
+ @Override
+ public void doFrame() {
+ lt.mInvalidationHandler.sendEvent(InvalidationHandler.MSG_TYPE_INVALIDATION, 0);
+ }
+}
diff --git a/lottie/src/main/java/com/airbnb/lottie/utils/SafeRunnable.java b/lottie/src/main/java/com/airbnb/lottie/utils/SafeRunnable.java
new file mode 100644
index 0000000000000000000000000000000000000000..ee20dd1ca5ae634ca000858cca79fafd3efd75c8
--- /dev/null
+++ b/lottie/src/main/java/com/airbnb/lottie/utils/SafeRunnable.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.airbnb.lottie.utils;
+
+/**
+ * 功能描述
+ */
+abstract class SafeRunnable implements Runnable {
+
+ LottieValueAnimator lt;
+ SafeRunnable( LottieValueAnimator ltAnimator) {
+ lt = ltAnimator;
+ }
+
+ @Override
+ public final void run() {
+ try {
+ doFrame();
+ } catch (Throwable throwable) {
+ final Thread.UncaughtExceptionHandler uncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
+ if (uncaughtExceptionHandler != null) {
+ uncaughtExceptionHandler.uncaughtException(Thread.currentThread(), throwable);
+ }
+ throw throwable;
+ }
+ }
+
+ abstract void doFrame();
+}