我有个问题。我用逐帧动画编写了用于Android的动态壁纸,并且我已经完成了动画,但是动画播放的速度非常慢,大约每秒1帧。
这是我的代码
public class WallpaperSer extends WallpaperService {
static final Handler mHandler = new Handler();
public void onCreate() {
super.onCreate();
}
public void onDestroy() {
super.onDestroy();
}
public Engine onCreateEngine() {
return new WallpaperSerEngine();
}
class WallpaperSerEngine extends Engine {
private boolean mVisible;
private float mScaleX;
private float mScaleY;
private Bitmap icon;
private Runnable diwaliImg;
int i = 0;
int[] pirates = {
R.drawable.final_0001,
R.drawable.final_0002,
R.drawable.final_0003,
R.drawable.final_0004,
R.drawable.final_0005,
R.drawable.final_0006,
R.drawable.final_0007,
R.drawable.final_0008,
R.drawable.final_0009,
R.drawable.final_0010,
R.drawable.final_0011,
R.drawable.final_0012,
R.drawable.final_0013,
R.drawable.final_0014,
R.drawable.final_0015,
R.drawable.final_0016,
R.drawable.final_0017,
R.drawable.final_0018,
R.drawable.final_0019,
R.drawable.final_0020,
R.drawable.final_0021,
R.drawable.final_0022,
R.drawable.final_0023,
R.drawable.final_0024,
R.drawable.final_0025,
R.drawable.final_0026,
R.drawable.final_0027,
R.drawable.final_0028,
R.drawable.final_0029,
R.drawable.final_0030,
R.drawable.final_0031,
R.drawable.final_0032,
R.drawable.final_0033,
R.drawable.final_0034,
R.drawable.final_0035,
R.drawable.final_0036,
R.drawable.final_0037,
R.drawable.final_0038,
R.drawable.final_0039,
R.drawable.final_0040,
R.drawable.final_0041,
R.drawable.final_0042,
R.drawable.final_0043,
R.drawable.final_0044,
R.drawable.final_0045,
R.drawable.final_0046,
R.drawable.final_0047,
R.drawable.final_0048,
R.drawable.final_0049,
R.drawable.final_0050,
R.drawable.final_0051,
R.drawable.final_0052,
R.drawable.final_0053,
R.drawable.final_0054,
R.drawable.final_0065,
R.drawable.final_0056,
R.drawable.final_0057,
R.drawable.final_0058,
R.drawable.final_0059,
R.drawable.final_0060,
R.drawable.final_0061,
R.drawable.final_0062,
R.drawable.final_0063,
R.drawable.final_0064,
R.drawable.final_0065,
R.drawable.final_0066,
R.drawable.final_0067,
R.drawable.final_0068,
R.drawable.final_0069,
R.drawable.final_0070,
R.drawable.final_0071,
R.drawable.final_0072,
R.drawable.final_0073,
R.drawable.final_0074,
R.drawable.final_0075,
R.drawable.final_0076,
R.drawable.final_0077,
R.drawable.final_0078,
R.drawable.final_0079,
R.drawable.final_0080,
R.drawable.final_0081,
R.drawable.final_0082,
R.drawable.final_0083,
R.drawable.final_0084,
R.drawable.final_0085,
R.drawable.final_0086,
R.drawable.final_0087,
R.drawable.final_0088,
R.drawable.final_0089,
R.drawable.final_0090,
R.drawable.final_0091,
R.drawable.final_0092,
R.drawable.final_0093,
R.drawable.final_0094,
R.drawable.final_0095,
R.drawable.final_0096,
R.drawable.final_0097,
R.drawable.final_0098,
R.drawable.final_0099,
R.drawable.final_0100,
R.drawable.final_0101,
R.drawable.final_0102,
R.drawable.final_0103,
R.drawable.final_0104,
R.drawable.final_0105,
R.drawable.final_0106,
R.drawable.final_0107,
R.drawable.final_0108,
R.drawable.final_0109,
R.drawable.final_0110,
R.drawable.final_0111,
R.drawable.final_0112,
R.drawable.final_0113,
R.drawable.final_0114,
R.drawable.final_0115,
R.drawable.final_0116,
R.drawable.final_0117,
R.drawable.final_0118,
R.drawable.final_0119,
R.drawable.final_0120
};
WallpaperSerEngine() {
diwaliImg = new Runnable() {
public void run() {
drawFrame();
}
};
}
@Override
public void onCreate(SurfaceHolder holder){
super.onCreate(holder);
}
@Override
public void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(diwaliImg);
}
@Override
public void onVisibilityChanged(boolean visible) {
mVisible = visible;
if (visible) {
drawFrame();
} else {
mHandler.removeCallbacks(diwaliImg);
}
}
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
drawFrame();
mScaleX = width / (1f * icon.getWidth());
mScaleY = height / (1f * icon.getHeight());
}
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
super.onSurfaceCreated(holder);
}
@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
mVisible = false;
mHandler.removeCallbacks(diwaliImg);
}
@Override
public void onOffsetsChanged(float xOffset, float yOffset, float xStep,float yStep, int xPixels, int yPixels) {
drawFrame();
}
@Override
public void onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
}
private void drawFrame() {
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
drawPirate(c);
}
} finally {
if (c != null)
holder.unlockCanvasAndPost(c);
}
mHandler.removeCallbacks(diwaliImg);
if (mVisible) {
mHandler.postDelayed(diwaliImg, 1000 / 25);
}
}
private void drawPirate(Canvas c) {
icon = BitmapFactory.decodeResource(getResources(), pirates[i]);
i++;
if (i == 120) {
i = 0;
}
Matrix matrix = new Matrix();
c.scale(mScaleX, mScaleY);
c.drawBitmap(icon, matrix, null);
icon.recycle();
}
}
}
我做错了什么?
更新1
我的错误日志带有@chipopo代码:
java.lang.IllegalArgumentException:解码到现有的问题
位图
在android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:482)
在dajver.com.framebyframelivewallpaper.WallpaperSer $ WallpaperSerEngine.setToFrame(WallpaperSer.java:188)
在dajver.com.framebyframelivewallpaper.WallpaperSer $ WallpaperSerEngine.drawPirate(WallpaperSer.java:266)
在dajver.com.framebyframelivewallpaper.WallpaperSer $ WallpaperSerEngine.drawFrame(WallpaperSer.java:253)
在dajver.com.framebyframelivewallpaper.WallpaperSer $ WallpaperSerEngine.onSurfaceChanged(WallpaperSer.java:219)
在android.service.wallpaper.WallpaperService $ Engine.updateSurface(WallpaperService.java:783)
在android.service.wallpaper.WallpaperService $ Engine.attach(WallpaperService.java:890)
在android.service.wallpaper.WallpaperService $ IWallpaperEngineWrapper.executeMessage(WallpaperService.java:1157)
在com.android.internal.os.HandlerCaller $ MyHandler.handleMessage(HandlerCaller.java:37)
在android.os.Handler.dispatchMessage(Handler.java:102)
在android.os.Looper.loop(Looper.java:135)
在android.app.ActivityThread.main(ActivityThread.java:5221)
在java.lang.reflect.Method.invoke(本机方法)
在java.lang.reflect.Method.invoke(Method.java:372)
在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:899)
在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
和我的代码与@chipppo编写的修复程序
public class WallpaperSer extends WallpaperService {
static final Handler mHandler = new Handler();
public void onCreate() {
super.onCreate();
}
public void onDestroy() {
super.onDestroy();
}
public Engine onCreateEngine() {
return new WallpaperSerEngine();
}
class WallpaperSerEngine extends Engine {
private boolean mVisible;
private float mScaleX;
private float mScaleY;
private Bitmap icon;
private Runnable diwaliImg;
int i = 0;
int[] pirates = {
R.drawable.final_0001,
R.drawable.final_0002,
R.drawable.final_0003,
R.drawable.final_0004,
R.drawable.final_0005,
R.drawable.final_0006,
R.drawable.final_0007,
R.drawable.final_0008,
R.drawable.final_0009,
R.drawable.final_0010,
R.drawable.final_0011,
R.drawable.final_0012,
R.drawable.final_0013,
R.drawable.final_0014,
R.drawable.final_0015,
R.drawable.final_0016,
R.drawable.final_0017,
R.drawable.final_0018,
R.drawable.final_0019,
R.drawable.final_0020,
R.drawable.final_0021,
R.drawable.final_0022,
R.drawable.final_0023,
R.drawable.final_0024,
R.drawable.final_0025,
R.drawable.final_0026,
R.drawable.final_0027,
R.drawable.final_0028,
R.drawable.final_0029,
R.drawable.final_0030,
R.drawable.final_0031,
R.drawable.final_0032,
R.drawable.final_0033,
R.drawable.final_0034,
R.drawable.final_0035,
R.drawable.final_0036,
R.drawable.final_0037,
R.drawable.final_0038,
R.drawable.final_0039,
R.drawable.final_0040,
R.drawable.final_0041,
R.drawable.final_0042,
R.drawable.final_0043,
R.drawable.final_0044,
R.drawable.final_0045,
R.drawable.final_0046,
R.drawable.final_0047,
R.drawable.final_0048,
R.drawable.final_0049,
R.drawable.final_0050,
R.drawable.final_0051,
R.drawable.final_0052,
R.drawable.final_0053,
R.drawable.final_0054,
R.drawable.final_0065,
R.drawable.final_0056,
R.drawable.final_0057,
R.drawable.final_0058,
R.drawable.final_0059,
R.drawable.final_0060,
R.drawable.final_0061,
R.drawable.final_0062,
R.drawable.final_0063,
R.drawable.final_0064,
R.drawable.final_0065,
R.drawable.final_0066,
R.drawable.final_0067,
R.drawable.final_0068,
R.drawable.final_0069,
R.drawable.final_0070,
R.drawable.final_0071,
R.drawable.final_0072,
R.drawable.final_0073,
R.drawable.final_0074,
R.drawable.final_0075,
R.drawable.final_0076,
R.drawable.final_0077,
R.drawable.final_0078,
R.drawable.final_0079,
R.drawable.final_0080,
R.drawable.final_0081,
R.drawable.final_0082,
R.drawable.final_0083,
R.drawable.final_0084,
R.drawable.final_0085,
R.drawable.final_0086,
R.drawable.final_0087,
R.drawable.final_0088,
R.drawable.final_0089,
R.drawable.final_0090,
R.drawable.final_0091,
R.drawable.final_0092,
R.drawable.final_0093,
R.drawable.final_0094,
R.drawable.final_0095,
R.drawable.final_0096,
R.drawable.final_0097,
R.drawable.final_0098,
R.drawable.final_0099,
R.drawable.final_0100,
R.drawable.final_0101,
R.drawable.final_0102,
R.drawable.final_0103,
R.drawable.final_0104,
R.drawable.final_0105,
R.drawable.final_0106,
R.drawable.final_0107,
R.drawable.final_0108,
R.drawable.final_0109,
R.drawable.final_0110,
R.drawable.final_0111,
R.drawable.final_0112,
R.drawable.final_0113,
R.drawable.final_0114,
R.drawable.final_0115,
R.drawable.final_0116,
R.drawable.final_0117,
R.drawable.final_0118,
R.drawable.final_0119,
R.drawable.final_0120
};
private Bitmap mainBitmap;
private BitmapFactory.Options mBitmapOptions;
private int currentFrameIndex = 0;
WallpaperSerEngine() {
diwaliImg = new Runnable() {
public void run() {
drawFrame();
}
};
initMainBitmap(getResources(), pirates[0]);
}
private void initMainBitmap(Resources res,int resId){
mBitmapOptions = new BitmapFactory.Options();
mBitmapOptions.inJustDecodeBounds = true;
mBitmapOptions.inMutable = true;
BitmapFactory.decodeResource(res, resId,mBitmapOptions);
mainBitmap = Bitmap.createBitmap(mBitmapOptions.outWidth,mBitmapOptions.outHeight,Bitmap.Config.ARGB_8888);
mBitmapOptions.inJustDecodeBounds = false;
mBitmapOptions.inBitmap = mainBitmap;//will cause the bitmap to be reused.
mBitmapOptions.inSampleSize = 1;
}
public boolean setToFrame(int frameIndex){
if(pirates != null && frameIndex >= 0 && frameIndex< pirates.length){
currentFrameIndex = frameIndex;
mainBitmap = BitmapFactory.decodeResource(getResources(), pirates[currentFrameIndex], mBitmapOptions);
return true;
}
else return false;
}
@Override
public void onCreate(SurfaceHolder holder){
super.onCreate(holder);
}
@Override
public void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(diwaliImg);
}
@Override
public void onVisibilityChanged(boolean visible) {
mVisible = visible;
if (visible) {
drawFrame();
} else {
mHandler.removeCallbacks(diwaliImg);
}
}
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
drawFrame();
mScaleX = width / (1f * icon.getWidth());
mScaleY = height / (1f * icon.getHeight());
}
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
super.onSurfaceCreated(holder);
}
@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
mVisible = false;
mHandler.removeCallbacks(diwaliImg);
}
@Override
public void onOffsetsChanged(float xOffset, float yOffset, float xStep,float yStep, int xPixels, int yPixels) {
drawFrame();
}
@Override
public void onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
}
private void drawFrame() {
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
drawPirate(c);
}
} finally {
if (c != null)
holder.unlockCanvasAndPost(c);
}
mHandler.removeCallbacks(diwaliImg);
if (mVisible) {
mHandler.postDelayed(diwaliImg, 1000 / 24);
}
}
private void drawPirate(Canvas c) {
setToFrame(i);
i++;
if (i == 120) {
i = 0;
}
Matrix matrix = new Matrix();
c.scale(mScaleX, mScaleY);
c.drawBitmap(mainBitmap, matrix, null);
}
}
}
最佳答案
对BitmapFactory.decodeResource(getResources(),pirates [i])的调用;创建一个新的位图。
我假设您的图像都具有相同的大小,因此您可以回收一个位图,而不是在每次图像更改时都创建一个新的位图。这将大大提高您的FPS。
回收位图:
private Bitmap mainBitmap;
private BitmapFactory.Options mBitmapOptions;
private void initMainBitmap(Resources res,int resId){
mBitmapOptions = new BitmapFactory.Options();
mBitmapOptions.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId,mBitmapOptions);
mainBitmap = Bitmap.createBitmap(mBitmapOptions.outWidth,mBitmapOptions.outHeight,Bitmap.Config.ARGB_8888);
mBitmapOptions.inJustDecodeBounds = false;
mBitmapOptions.inBitmap = mainBitmap;//will cause the bitmap to be reused.
mBitmapOptions.inSampleSize = 1;
}
private int currentFrameIndex = 0;
public boolean setToFrame(int frameIndex){
if(pirates != null && frameIndex >= 0 && frameIndex< pirates.length){
currentFrameIndex = frameIndex;
mainBitmap = BitmapFactory.decodeResource(mResources, pirates[currentFrameIndex],mBitmapOptions);
return true;
}
else return false;
}
使用此代码:
从引擎构造函数调用initMainBitmap函数:
WallpaperSerEngine() {
diwaliImg = new Runnable() {
public void run() {
drawFrame();
}
};
initMainBitmap(getResources(),pirates[0]);
}
您的drawPirate应该更改为:
private void drawPirate(Canvas c) {
setToFrame(i);
i++;
if (i == 120) {
i = 0;
}
Matrix matrix = new Matrix();
c.scale(mScaleX, mScaleY);
c.drawBitmap(mainBitmap, matrix, null);
}