Ill*_*ent 15 android android-animation
我试图通过在imageview中更改图像来逐帧动画显示.我尝试在xml中绘制动画,并在Handler中更改imageview的位图.我还试图在arraylist中存储三个位图(以避免内存不足)作为缓存机制,但实际上是很低的改进.我需要迭代36张图像以获得完整的动画效果.我面临的问题是,在我使用的所有方法中,我无法在50ms的给定时间范围内完成动画.图像范围从最小250 kb到最大540 kb.动画的fps非常低.随着应用程序的ios版本准备就绪,我被限制为显示与ios版本一致的动画.我是renderscript和opengl的菜鸟.有没有办法在50-60ms内显示大图像的平滑动画.任何提示或建议都非常感谢.下面是动画的快照:这是任何一个感兴趣的人的图像链接.

我写了一个简单的活动,它做了最基本的事情:
加载Thread中的所有位图,然后每隔40ms将更改发布到ImageView.
package mk.testanimation;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.ImageView;
import java.util.ArrayList;
public class MainActivity extends Activity {
ImageView mImageView;
private int mImageRes[] = new int[]{
R.drawable.s0,
R.drawable.s1,
R.drawable.s2,
R.drawable.s3,
R.drawable.s4,
R.drawable.s5,
R.drawable.s6,
R.drawable.s7,
R.drawable.s8,
R.drawable.s9,
R.drawable.s10,
R.drawable.s11,
R.drawable.s12,
R.drawable.s13,
R.drawable.s14,
R.drawable.s15,
R.drawable.s16,
R.drawable.s17,
R.drawable.s18,
R.drawable.s19,
R.drawable.s20,
R.drawable.s21,
R.drawable.s22,
R.drawable.s23,
R.drawable.s24,
R.drawable.s25,
R.drawable.s26,
R.drawable.s27,
R.drawable.s28,
R.drawable.s29,
R.drawable.s30,
R.drawable.s31,
R.drawable.s32,
R.drawable.s33,
R.drawable.s34,
R.drawable.s35,
};
private ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(mImageRes.length);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Handler handler = new Handler();
mImageView = new ImageView(this);
setContentView(mImageView);
Thread important = new Thread() {
@Override
public void run() {
long timestamp = System.currentTimeMillis();
for (int i = 0; i < mImageRes.length; i++) {
mBitmaps.add(BitmapFactory.decodeResource(getResources(), mImageRes[i]));
}
Log.d("ANIM-TAG", "Loading all bitmaps took " + (System.currentTimeMillis() - timestamp) + "ms");
for (int i = 0; i < mBitmaps.size(); i++) {
final int idx = i;
handler.postDelayed(new Runnable() {
@Override
public void run() {
mImageView.setImageBitmap(mBitmaps.get(idx));
}
}, i * 40);
}
}
};
important.setPriority(Thread.MAX_PRIORITY);
important.start();
}
}
Run Code Online (Sandbox Code Playgroud)
在我的Nexus 7上看起来相当不错,但加载所有位图确实需要4s多一点.
你能提前加载位图吗?
此外,它不会节省一吨,但你的pngs在透明空间周围有一堆填充物.您可以裁剪它们并减少内存.否则压缩图像也会有所帮助(比如限制使用的颜色数量).
理想情况下,在上述解决方案中,您可以在不再使用位图后立即回收这些位图.
另外,如果内存太大,你可以像你提到的那样做,并且有一个Bitmap缓冲区,但我很确定它需要超过3个图像大.
祝好运.
编辑:尝试2.首先,我将所有图像裁剪为590x590.这削减了大约1mb的图像.然后我创建了一个新类,它有点"忙"并且没有固定的帧速率,但是在它们准备好后立即呈现图像:
package mk.testanimation;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.ImageView;
import java.util.ArrayList;
public class MainActivity extends Activity {
ImageView mImageView;
private int mImageRes[] = new int[]{R.drawable.s0, R.drawable.s1, R.drawable.s2, R.drawable.s3, R.drawable.s4, R.drawable.s5, R.drawable.s6, R.drawable.s7, R.drawable.s8, R.drawable.s9, R.drawable.s10, R.drawable.s11, R.drawable.s12, R.drawable.s13, R.drawable.s14, R.drawable.s15, R.drawable.s16, R.drawable.s17, R.drawable.s18, R.drawable.s19, R.drawable.s20, R.drawable.s21, R.drawable.s22, R.drawable.s23, R.drawable.s24, R.drawable.s25, R.drawable.s26, R.drawable.s27, R.drawable.s28, R.drawable.s29, R.drawable.s30, R.drawable.s31, R.drawable.s32, R.drawable.s33, R.drawable.s34, R.drawable.s35};
private ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(mImageRes.length);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final long timestamp = System.currentTimeMillis();
final Handler handler = new Handler();
mImageView = new ImageView(this);
setContentView(mImageView);
Thread important = new Thread() {
@Override
public void run() {
for (int i = 0; i < mImageRes.length; i++) {
mBitmaps.add(BitmapFactory.decodeResource(getResources(), mImageRes[i]));
}
}
};
important.setPriority(Thread.MAX_PRIORITY);
important.start();
Thread drawing = new Thread() {
@Override
public void run() {
int i = 0;
while (i < mImageRes.length) {
if (i >= mBitmaps.size()) {
Thread.yield();
} else {
final Bitmap bitmap = mBitmaps.get(i);
handler.post(new Runnable() {
@Override
public void run() {
mImageView.setImageBitmap(bitmap);
}
});
i++;
}
}
Log.d("ANIM-TAG", "Time to render all frames:" + (System.currentTimeMillis() - timestamp) + "ms");
}
};
drawing.setPriority(Thread.MAX_PRIORITY);
drawing.start();
}
}
Run Code Online (Sandbox Code Playgroud)
上面的渲染几乎立即开始,我的2012 Nexus 7花了不到4秒.
作为最后的努力,我将所有图像转换为8位PNG而不是32位.这使渲染不到2秒!
我敢打赌,你最终得到的任何解决方案都将受益于使图像尽可能小.
再次 - 祝你好运!