Ответ 1
Я написал простую деятельность, которая делает самую основную вещь:
Загружает все растровые изображения в потоке, затем отправляет изменения в ImageView каждые 40 мс.
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();
}
}
Это выглядело довольно прилично на моем Nexus 7, но для загрузки всех растровых изображений потребовалось немного больше 4 секунд.
Можете ли вы загружать растровые изображения заранее?
Кроме того, он не будет экономить тонну, но ваши png имеют кучу прокладок вокруг прозрачного пространства. Вы можете обрезать их и немного уменьшить память. В противном случае сжатие изображений также поможет (например, ограничение количества используемых цветов).
В идеале, в приведенном выше решении, вы должны переработать растровые изображения сразу же после того, как они больше не будут использоваться.
Кроме того, если это слишком тяжело для памяти, вы можете сделать то, что вы упомянули, и иметь битмарт-буфер, но я уверен, что это должно быть больше трех изображений.
Удачи.
РЕДАКТИРОВАТЬ: Попытка 2. Во-первых, я обрезал все изображения до 590x590. Это бритая около 1 мб изображений. Затем я создал новый класс, который немного "занят" и не имеет фиксированной частоты кадров, но отображает изображения, как только они будут готовы:
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();
}
}
Вышеуказанное начало рендеринга начинаться почти сразу, и на моем 2012 Nexus 7 потребовалось меньше 4 секунд.
В качестве последнего усилия я преобразовал все изображения в 8-разрядные PNG вместо 32-разрядных. Это привело к рендерингу менее 2 секунд!
Я готов поспорить, что любое решение, в котором вы закончите, поможет сделать изображения как можно меньше.
Снова - удача!