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



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

这就是我用来创建可绘制的的方法

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中添加一些ImageViews:

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);
}

对您来说,最好的做法可能是使用traceview来评测执行情况,因为这将使您充分了解应用程序的大部分执行时间都花在了哪里。然后,您可以集中精力优化特定的代码段。

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

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

相关内容

  • 没有找到相关文章

最新更新