android 求助啊。救命。
我开发安卓的图书软件。有比较多的图。。 我每次转跳时。只是把图片清空null 发现这样不行。还会引起内存不足。崩溃退出。
代码如下
mAppIcons = (ImageView)findViewById(R.id.jianfeiimageView1);
bmps=BitmapFactory.decodeResource(qianyan3.this.getResources(),R.drawable.lishi1001);
mAppIcons.setImageBitmap(bmps);
if(!bmps.isRecycled()){//先判断图片是否已释放了
bmps.recycle();
}
日志 FATAL EXCEPTION main
java.lang.RuntimeEXception: CanVas: trying to use a recycled bitmap android .graphics.Bitmap@407b7840 --------------------编程问答-------------------- 你的问题恰恰是因为你的imageview用到的bitmap 被你recycle了,所以你的recycle()方法 不能够放到setIamgeBitmap 方法后面 ,我觉得是因为iamgeview的draw()方法是一个不断重绘的方法 你在下一步就让bitmap 回收了 再绘制时引用的 就会是回收的bitmap 自然会报错;
所以你的实现方式不对 ,这个真的不好控制 你最多只能调用 system.gc()方法 然后还有一个优化方式是 控制bitmapfactory 取bitmap的option 选项 这个option 你可以传你自己特定的值 便于减小你的bitmap的大小
BitmapFactory.decodeResourceStream(this.getResources(), new TypedValue(),
this.getAssets().open("xxx.png"), new Rect(), mOption);
而关于option的配置可以这样:
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(dm);
mOptions = new BitmapFactory.Options();
mOptions.inPreferredConfig = Bitmap.Config.RGB_565;
mOptions.inDither = true;
mOptions.inScreenDensity = dm.densityDpi;
mOptions.inDensity = 160;
mOptions.inSampleSize = 1;
这个可以根据你自己再查查资料 看看 具体的每个属性是干什么用的 --------------------编程问答-------------------- 谢谢。我调整下看看 --------------------编程问答-------------------- 有用。在activity启动时关闭时。分别加上回收system.gc() 就好了很多。 --------------------编程问答--------------------
你在试试option选项的设置 比如改变density之类的 可以进一步的改变bitmap的大小 --------------------编程问答-------------------- --------------------编程问答--------------------
--------------------编程问答-------------------- 大图这样处理一下吧,recycle不推荐使用的。
01./**
02. * 加载大图片工具类:解决android加载大图片时报OOM异常
03. * 解决原理:先设置缩放选项,再读取缩放的图片数据到内存,规避了内存引起的OOM
07. */
08.public class BitmapUtil {
09.
10. public static final int UNCONSTRAINED = -1;
11.
12. /*
13. * 获得设置信息
14. */
15. public static Options getOptions(String path){
16. Options options = new Options();
17. options.inJustDecodeBounds = true;//只描边,不读取数据
18. BitmapFactory.decodeFile(path, options);
19. return options;
20. }
21.
22.
23. /**
24. * 获得图像
25. * @param path
26. * @param options
27. * @return
28. * @throws FileNotFoundException
29. */
30. public static Bitmap getBitmapByPath(String path, Options options , int screenWidth , int screenHeight)throws FileNotFoundException{
31. File file = new File(path);
32. if(!file.exists()){
33. throw new FileNotFoundException();
34. }
35. FileInputStream in = null;
36. in = new FileInputStream(file);
37. if(options != null){
38. Rect r = getScreenRegion(screenWidth,screenHeight);
39. int w = r.width();
40. int h = r.height();
41. int maxSize = w > h ? w : h;
42. int inSimpleSize = computeSampleSize(options, maxSize, w * h);
43. options.inSampleSize = inSimpleSize; //设置缩放比例
44. options.inJustDecodeBounds = false;
45. }
46. Bitmap b = BitmapFactory.decodeStream(in, null, options);
47. try {
48. in.close();
49. } catch (IOException e) {
50. e.printStackTrace();
51. }
52. return b;
53. }
54.
55.
56.
57. private static Rect getScreenRegion(int width , int height) {
58. return new Rect(0,0,width,height);
59. }
60.
61.
62. /**
63. * 获取需要进行缩放的比例,即options.inSampleSize
64. * @param options
65. * @param minSideLength
66. * @param maxNumOfPixels
67. * @return
68. */
69. public static int computeSampleSize(BitmapFactory.Options options,
70. int minSideLength, int maxNumOfPixels) {
71. int initialSize = computeInitialSampleSize(options, minSideLength,
72. maxNumOfPixels);
73.
74. int roundedSize;
75. if (initialSize <= 8) {
76. roundedSize = 1;
77. while (roundedSize < initialSize) {
78. roundedSize <<= 1;
79. }
80. } else {
81. roundedSize = (initialSize + 7) / 8 * 8;
82. }
83.
84. return roundedSize;
85. }
86.
87. private static int computeInitialSampleSize(BitmapFactory.Options options,
88. int minSideLength, int maxNumOfPixels) {
89. double w = options.outWidth;
90. double h = options.outHeight;
91.
92. int lowerBound = (maxNumOfPixels == UNCONSTRAINED) ? 1 :
93. (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
94. int upperBound = (minSideLength == UNCONSTRAINED) ? 128 :
95. (int) Math.min(Math.floor(w / minSideLength),
96. Math.floor(h / minSideLength));
97.
98. if (upperBound < lowerBound) {
99. // return the larger one when there is no overlapping zone.
100. return lowerBound;
101. }
102.
103. if ((maxNumOfPixels == UNCONSTRAINED) &&
104. (minSideLength == UNCONSTRAINED)) {
105. return 1;
106. } else if (minSideLength == UNCONSTRAINED) {
107. return lowerBound;
108. } else {
109. return upperBound;
110. }
111. }
112.
113.
114.}
调用方法:
--------------------编程问答-------------------- 就算用了bmp.recycle 或是system.gc()都不能百分百的立既回收空间,这是java处理机制与C/C++相比的缺陷,
String path = "/sdcard/test2.jpg";
try {
//screenWidth,screenHeight为屏幕大小,也可设置为你需要让图片显示的大小
Bitmap bitmap = BitmapUtil.getBitmapByPath(path, BitmapUtil.getOptions(path), screenWidth, screenHeight);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
图片内存占用是有限制的16M,这其中也包括底层C的使用空间,还有一些压缩旋转会使图片内存增大.
你的问题是,图片正在使用你就清理了 --------------------编程问答-------------------- 如上所述 --------------------编程问答-------------------- 我每次遇到处理图片的问题 总是优先选择Matrix去处理,可以对图片进行任何处理,很少遇到问题,你setImage的时候最好进行压缩下,或者1楼的也可以 --------------------编程问答--------------------
补充:移动开发 , Android