我喜欢使用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
(文档链接)。特别是,您应该能够使用inScaled
、inDensity
和inTargetDensity
选项的组合来执行所需的所有缩放。如果将这些代码传递给decodeStream()
方法,则可能会在返回之前删除所有用于调整图像大小的后续代码。