lottie加载动画,第一次有延迟问题

lottie是airbnb推出的一个直接将AE工程转化为动画的工具。

ae.project-->data.json-->LottieComposition-->Lottie动画

之前做一个比较复杂的动画,花了两天时间都在画各种弧,计算运动轨迹等等。感觉我不是在编程,我是在算数学。

上lottie的过程,花了半天时间调AE动画,因为设计师的电脑上装插件没装成功。所以AE转json文件的过程都抛给了开发。

原本做第一个动画就花了2天,现在4个动画,我几分钟全搞定了。设计想怎么改,就怎么改,我无非是替换一下json文件就可以了,真是痛快。在设计眼皮下,一像素一像素调UI,我觉得是最浪费时间的事。

说说碰到的这个问题吧:

场景:第一打开Activity的时候,动画过了0.3s才显示出来,好点的手机不会,老点的手机就比较明显。

分析了一下源码

public void setAnimation(@RawRes final int animationResId, final CacheStrategy cacheStrategy) {
    this.animationResId = animationResId;
    animationName = null;
    if (RAW_RES_WEAK_REF_CACHE.indexOfKey(animationResId) > 0) {
      WeakReference compRef = RAW_RES_WEAK_REF_CACHE.get(animationResId);
      LottieComposition ref = compRef.get();
      if (ref != null) {
        setComposition(ref);
        return;
      }
    } else if (RAW_RES_STRONG_REF_CACHE.indexOfKey(animationResId) > 0) {
      setComposition(RAW_RES_STRONG_REF_CACHE.get(animationResId));
      return;
    }

    clearComposition();
    cancelLoaderTask();
    compositionLoader = LottieComposition.Factory.fromRawFile(getContext(), animationResId,
        new OnCompositionLoadedListener() {
          @Override public void onCompositionLoaded(LottieComposition composition) {
            if (cacheStrategy == CacheStrategy.Strong) {
              RAW_RES_STRONG_REF_CACHE.put(animationResId, composition);
            } else if (cacheStrategy == CacheStrategy.Weak) {
              RAW_RES_WEAK_REF_CACHE.put(animationResId, new WeakReference<>(composition));
            }

            setComposition(composition);
          }
        });
  }

setAnimation的过程,会先从cache中取,如果没有就自己构造一个Composition,composition中包含了所有的动画描述信息。

所以问题就出在了composition的构造

/**
     * Loads a composition from a json reader.
     * 

* ex: fromInputStream(context, new FileInputStream(filePath), (composition) -> {}); */ public static Cancellable fromJsonReader( JsonReader reader, OnCompositionLoadedListener listener) { AsyncCompositionLoader loader = new AsyncCompositionLoader(listener); loader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, reader); return loader; }

不断跟进LottieComposition.Factory中的fromRawFile()方法,最终发现AsyncCompositionLoader,问题就出来了,从ae产物json动画描述文件的解析过程是一个异步的过程,自然会影响到动画的第一打开的速度。

对于起步时间敏感的动画,有没有同步的方法给我们调一调呢?

搜了下sync关键字,果然有。

public static LottieComposition fromJsonSync(JsonReader reader) throws IOException {
      return LottieCompositionParser.parse(reader);
    }

然后我们再倒着找最外层封装好的方法:

/**
     * Loads a composition from a file stored in /assets.
     */
    public static Cancellable fromAssetFileName(
        Context context, String fileName, OnCompositionLoadedListener listener) {
      InputStream stream;
      try {
        stream = context.getAssets().open(fileName);
      } catch (IOException e) {
        throw new IllegalArgumentException("Unable to find file " + fileName, e);
      }
      return fromInputStream(stream, listener);
    }

可以可以,就是这个了,把原来xml中的data.json复制一份放在asset目录下,

LottieAnimationView lottieAnimationView = findViewById(R.id.animation_view);
        LottieComposition composition = LottieComposition.Factory.fromFileSync(this,"data.json");
        lottieAnimationView.setComposition(composition);

运行一下,OK,延迟消失了。

当然异步加载有异步的好处。大家可以根据自己的需要来选择同步异步,或者是否需要CacheStrategy来做强缓存,或者弱缓存,提高加载的速度。

你可能感兴趣的:(Android)