电池消耗自定义动画绘制 [英] Battery consumption with custom animated drawable

查看:161
本文介绍了电池消耗自定义动画绘制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Loooong时查看器,终于等到一轮在这里计算器注册!

Loooong time viewer, finally getting round to signing up here at StackOverflow!

在一个很长的时间寻找一种方式做在Android上的ViewGroup的滚动背景下,我已经开发了以下内容:

After a very long time searching for a way to do a scrolling background of a ViewGroup in Android, I've developed the following:

public class SlidingDrawable extends Drawable implements Drawable.Callback {
private static final String TAG = "SlidingDraw";
private static float STEP_SIZE = 1.0f;

private BitmapDrawable mBitmap;
private Context mContext;

private float mPosX;
private int mBitmapWidth;

private Runnable mInvalidater;
private Handler mHandler;

public SlidingDrawable(Context c){
    mContext = c;

    // use this as the callback as we're implementing the interface
    setCallback(this);

    mHandler = new Handler();
    mInvalidater = new Runnable(){
        @Override
        public void run(){
            // decrement the drawables step size
            mPosX -= SlidingDrawable.STEP_SIZE;

            /*
             * Check to see if the current position is at point where it should 
             * loop.  If so, reset back to 0 to restart
             */
            if(Math.abs(mPosX) >= mBitmapWidth) mPosX = 0;
            // redraw
            invalidateDrawable(null);
        }
    };
}
public static void setStepSize(float newSize){
    SlidingDrawable.STEP_SIZE = newSize;
}
public void createBitmap(String path, ViewGroup parent){
    // height of the parent container
    int height = parent.getHeight();

    /* Initialize local variables
     *  bgBitmap    - the resulting bitmap to send into SlidingDrawable instance
     *  imageStream - raw bitmap data to be decoded into bgBitmap
     */     
    WindowManager wMgr = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
    int mScreenWidth = wMgr.getDefaultDisplay().getWidth();

    InputStream imageStream;
    Matrix imgMatrix = new Matrix();
    Bitmap bitmap = null;
    try {
        imageStream = mContext.getAssets().open(path);

        // create a temporary bitmap object for basic data
        Bitmap temp = BitmapFactory.decodeStream(imageStream);
        int width = temp.getWidth();

        // find the width difference as a percentage to apply to the 
        // transformation matrix
        float widthDifference = ((float)mScreenWidth) / (float)(width / 2);
        imgMatrix.postScale(widthDifference, 0, 0f, 0f);

        // create a copy of the bitmap, scaled correctly to maintain loop
        bitmap = Bitmap.createScaledBitmap(temp, (int)(width * widthDifference), height, true);

        // recycle the temp bitmap
        temp.recycle();
    } catch (IOException e) {
        e.printStackTrace();
    }   
    mBitmap = new BitmapDrawable(bitmap);

    // required
    mBitmapWidth = getIntrinsicWidth() / 2;
    Rect bounds = new Rect(0, 0, getIntrinsicWidth(), getIntrinsicHeight());        
    setBounds(bounds);
}
@Override
public void draw(Canvas canvas) {
    canvas.drawBitmap(mBitmap.getBitmap(), mPosX, 0f, null);
    scheduleDrawable(this, mInvalidater, SystemClock.uptimeMillis());
}
@Override
public int getOpacity() {
    return PixelFormat.OPAQUE;
}

@Override
public void scheduleDrawable(Drawable who, Runnable what, long when) {
    mHandler.postAtTime(what, who, when);
}

@Override
public void unscheduleDrawable(Drawable who, Runnable what) {
    mHandler.removeCallbacks(what, who);
}
@Override
public void invalidateDrawable(Drawable who) {
    invalidateSelf();
}
/* 
 * Methods not directly used or called omitted
 * 
 */

}

这是在像这样的活动中:

It is used in the Activity like so:

@Override
public void onWindowFocusChanged(boolean focus){
    // set the background of the root view of main.xml
    SlidingDrawable drawable = new SlidingDrawable(getApplicationContext());
    drawable.createBitmap("bgimg/basebg.jpg", mRoot);
    mRoot.setBackgroundDrawable(drawable);
}

长话短说,在basebg.jpg图像是平铺图像大致1600x480。该构造SlidingDrawable秤的动作和yaddah yaddah。它的工作原理。

Long story short, the basebg.jpg image is a tileable image roughly 1600x480. The constructor for SlidingDrawable scales and moves and yaddah yaddah. It works.

现在的问题是,它似乎真的效率低下像这样做。我似乎无法找到这种实现的多的信息,所以我在那里我可以削减CPU周期,或者即使我使用的方法正确调用黑暗。

Now, the problem is, it seems really inefficient to do it like this. I can't seem to find much information on this sort of implementation, so I'm in the dark on where I can cut CPU cycles, or even if I'm using the method calls correctly.

我的问题包括:


  • 是更好地drawBitmap,而不是使用setTranslate()或的postTranslate并使用矩阵绘制位图?

  • 是它更好地使用drawBitmap或画布功能,如翻译(),保存(),并恢复()?

  • 率做什么draw()方法被调用时,是有办法将其限制,比方说,24 FPSØ限制重绘?

  • 到底是什么这类事情的当参数?在SystemClock.uptimeMillis传递()仅仅是工作的一个,试图通过增加一个+ 100或东西每隔100ms只是使它口吃火推迟它。

我研究这个,就像我可以......我把它留给计算器现在:)

I've researched this as much as I can... I'm leaving it to StackOverflow now :)

推荐答案

经过一段时间的画板,我简单的功能了。从本质上讲,它是发送无效()在每次调用 SystemClock.uptimeMillis(),做一重绘每一步更改。

After some time with the drawing board, I simplified the functions down. Essentially, it was sending an invalidate() call on every SystemClock.uptimeMillis(), doing one redraw for each step change.

所以,我删除了 Drawable.Callback 接口,并通过了 invalidateSelf()从处理程序直接调用,除去中介的接口方法,这似乎并没有做什么特别的呢。

So, I removed the Drawable.Callback interface and passed the invalidateSelf() call directly from the Handler, removing the intermediary interface methods, which didn't seem to do anything special anyway.

有使用的CPU使用率略有区别
drawBitmap(位图源,INT X,诠释Y,涂料P)
drawBitmap(位图源,矩阵的矩阵,涂料P),所以我选择了后者,以节省周期。

There was a slight difference in the CPU usage using drawBitmap(Bitmap source, int X, int Y, Paint p) vs. drawBitmap(Bitmap source, Matrix matrix, Paint p), so I opted for the latter to save cycles.

新方法如下:

// Runnable
mInvalidater = new Runnable(){
    @Override
    public void run(){
        // decrement the drawables step size
        mPosX -= SlidingDrawable.STEP_SIZE;
        if(Math.abs(mPosX) >= mBitmapWidth){
            mPosX = 0;
            mImageMatrix.setTranslate(0, 0);
        }
        mImageMatrix.postTranslate(-STEP_SIZE, 0);
        SlidingDrawable.this.invalidateSelf();
    }
};
// Draw method
@Override
public void draw(Canvas canvas) {
    canvas.drawBitmap(mBitmap.getBitmap(), mImageMatrix, null);
    mHandler.postAtTime(mInvalidater, SystemClock.uptimeMillis() + 64); 
}

我拔掉了电话,运行的应用程序进行1分钟左右,然后打开我的摩托Droid的电池使用测试电池的结果。之前,电池使用超过了显示器,现在坐在舒适的下面。

I tested the battery results by unplugging the phone, running the application for around a minute, then opening the battery usage on my Moto Droid. Before, the battery usage surpassed the Display, now it sits comfortably below.

愤怒的小鸟也是一个标杆,通过运行开始屏幕(其中BG卷轴,鸟儿到处飞)在相同的时间内,在某些情况下,我的应用程序坐在下面愤怒的小鸟,但并非总是如此。

Angry Birds was also a benchmark, by running the opening screen (where the bg scrolls and the birds fly everywhere) for the same amount of time, in some cases my app sat below Angry Birds, but not always.

CPU使用率是使用ADB shell命令检查 dumpsys cpuinfo 因为似乎是一个问题的查看CPU信息通过DDMS 的上上运行2.2的设备。

CPU usage was checked using the ADB shell command dumpsys cpuinfo as there seems to be a problem viewing CPU info on through the DDMS on devices running 2.2.

我仍然高达听到这个其他的想法,但现在,它解决了。

I'd still be up to hear other thoughts on this, but for now, it's solved.

这篇关于电池消耗自定义动画绘制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆