从assets文件夹中绘制drawable的自定义方法具有较高的cpu使用率

时间:2012-02-02 19:56:02

标签: android bitmap inputstream drawable android-assets

我喜欢使用assets文件夹而不是drawable文件夹(如果它不是九个补丁)因为我可以在那里使用多个文件夹。然而,我用来获得drawable的方法需要cpu做很多安静。例如:添加10个ImageView后需要10%的CPU(我使用Android Assistent和Samsung TouchWiz TaskManager)。我在写游戏时没有注意到它。现在这个游戏需要40-100%的CPU,即使它不在前台。

这是我用来创建drawable的方法:

public BitmapDrawable readAsset(path){
    try{

        inputStream = assetManager.open(path);
        //get the Bitmap
        desiredImg = BitmapFactory.decodeStream(inputStream, null, opts);
        //resize for other screen sizes (scale is calculated beforehand)
        scaleX =(int)(desiredImg.getWidth()/scale);
        scaleY = (int)(desiredImg.getHeight()/scale);

        //Bitmap to get config ARGB_8888 (createScaledBitmap returns RGB_565 => bad quality especially in gradients)
        //create empty bitmap with Config.ARGB_8888 with the needed size for drawable
        Bitmap temp = Bitmap.createBitmap(scaleX, scaleY, Config.ARGB_8888);
        //Canvas to draw desiredImg on temp
        Canvas canvas = new Canvas(temp);
        canvas.drawBitmap(convert, null, new Rect(0, 0, scaleX, scaleY), paint);

        //Convert to BitmapDrawable
        BitmapDrawable bitmapDrawable=new BitmapDrawable(temp);
        bitmapDrawable.setTargetDensity(metrics);

        inputStream.close();
        return bitmapDrawable;
    }catch (Exception e) {
        Log.d(TAG, "InputStream failed: "+e.getMessage());
    }
    return null;
}

我在应用程序中唯一做的就是使用此方法在RelativeLayout中添加一些ImageView:

private void addImageToContainer(int paddingLeft, int paddingTop) {
    ImageView imageView = new ImageView(this);
    imageView.setImageDrawable(assetReader.readAsset("test.jpg"));
    imageView.setPadding(paddingLeft, paddingTop, 0, 0);
    container.addView(imageView);
}

1 个答案:

答案 0 :(得分:1)

对你来说最好的事情可能是profile the execution with traceview,因为这可以让你充分了解你的应用程序花费大部分执行时间的位置。然后,您可以专注于优化特定的代码。

只是一个有根据的猜测,但我觉得大部分浪费的执行不是因为你从assets/而不是资源中提取图像,但所有的缩放工作都是在之后完成的(并且来自它的外观,这都是在主线程上完成的,因此没有并发性可言。)

我可能会建议您在解码资产时尝试利用可用的部分BitmapFactory.OptionsDocs link)。特别是,您应该能够结合inScaledinDensityinTargetDensity选项进行所需的所有缩放。如果您将这些传递给decodeStream()方法,则可能会在返回之前删除用于调整图像大小的所有后续代码。