私はこの問題に数日間取り組んできましたが、問題を解決できませんでした。
ユーザーがアプリケーションを使用している間、継続的に実行される Runnables として実装された多くのアニメーションがあります。logo_animation000 から 115 までと z_animation000 から 515 までの 4 つの異なるアニメーションがあります。
- ConnectingAnimation (アプリケーションがデバイスに接続している間に実行)
- ConnectingCompleteAnimation (接続が完了すると 1 回実行)
- TransitiontoSleepingAnimation(アプリの状態変化時に一度実行)
- SleepingAnimation(アプリケーションの状態が「スリープ中」のときに実行
これらのアニメーションは、通常のアニメーション リストを使用して動作させるには大きすぎるため、独自の実装を使用せざるを得ませんでした。次のクラスでこの問題を「解決」しました。
abstract class MyAnimationRunnable implements Runnable {
protected final int interval;
protected final String pattern;
protected final OptimisedImageView view;
protected long firstFrameAt;
protected int current;
protected Drawable drawable;
protected int frameCounter = 0;
public MyAnimationRunnable(int interval, int firstFrame, String pattern, OptimisedImageView view) {
this.interval = interval;
this.pattern = pattern;
this.view = view;
this.current = firstFrame;
this.firstFrameAt = SystemClock.elapsedRealtime();
handler.post(this);
}
@Override
public void run() {
final String name = String.format(Locale.ENGLISH, pattern, current);
final int id = getResources().getIdentifier(name, "drawable", getPackageName());
if (id != 0) {
final Drawable drawable = getResources().getDrawable(id);
view.setImageDrawable(drawable);
}
current++;
if (runAgain()) {
frameCounter++;
long nextAt = firstFrameAt + (frameCounter * interval);
long delay = nextAt - SystemClock.elapsedRealtime() - 1;
if (delay > 0) {
handler.postDelayed(this, delay);
} else {
this.run();
}
}
}
protected abstract boolean runAgain();
};
private void startSleepingAnimation()
{
zzzAnimation = new MyAnimationRunnable(50, 1, "z_animation%04d", zzzImageView) {
@Override
protected boolean runAgain() {
if (current == 510) {
current = 470; // this seems to fit into the infinite loop.
}
return true;
}
};
}
private void startConnectingAnimation() {
handler.removeCallbacks(connectingCompleteAnimation);
handler.removeCallbacks(zzzAnimation);
handler.removeCallbacks(transitionToSleepingAnimation);
connectingResourceCount = 1;
zzzImageView.setImageBitmap(null);
connectingAnimation = new MyAnimationRunnable(50, connectingResourceCount, "logo_animation%04d", babyImageView) {
@Override
protected boolean runAgain() {
if (current == 30) {
current = 1;
}
connectingResourceCount = current;
return true;
}
};
}
// The remaining two animations have been left out since this oughta be sufficient for understanding the code.
これは、Samsung Galaxy S3 で問題なく動作します。ただし、古い電話では、20 ~ 30 秒後にクラッシュが発生します。このコードをより軽量で効率的にする方法についてのアイデアはありますか?