从网上加载图片,老是报OutOfMemoryError,如何解决? 我用这个弱引用WeakReference但是总报空指针,我都没找出怎么出现的。很悲剧是不是WeakReference还有什么传说中的机关 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 楼主问下,你所谓的100多K是一张图片还是几张? 如果是一张的话,那么肯定是会outofmemery的。 vm 肯定不够用的。 子线程里面加载图片,一般来说稍微大一点都会OOM的,除非把加载放到父线程里面来。 这是部分代码,是一个继承baseadapter的适配器,用在Gallery里面@Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub final ImageView imgView = new ImageView(imgContext); imgView.setLayoutParams(new Gallery.LayoutParams(209, 123));// 设置布局图片大小 // imgvView.setClickable(true);// imgView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);// imgView.setBackgroundColor(0xFFFFFF); imgView.setPadding(5, 5, 5, 5);// 设置边框间距 imgView.setAdjustViewBounds(true);// 保持图片高宽比 // imgvView.setImageBitmap(urlarr[position]);// 设置图片源 final WeakReference<ImageView> imageViewReference = new WeakReference<ImageView>( imgView); final URL tempUrl = urlarr[position]; new Thread() { public void run() { try { Message msg = new Message(); msg.what = 0; HttpURLConnection urlcon = (HttpURLConnection) tempUrl .openConnection(); urlcon.setDoInput(true); urlcon.connect(); InputStream is = urlcon.getInputStream(); Bitmap tempBitmap = BitmapFactory.decodeStream(is); List<Object> myList = new ArrayList<Object>(); myList.add(tempBitmap); myList.add(imageViewReference); // myList.add(imgView); // imgvView.setImageBitmap(tempBitmap); msg.obj = myList; is.close(); imghHandler.sendMessage(msg); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }.start(); return imgView; } Handler imghHandler = new Handler() { /* * (non-Javadoc) * * @see android.os.Handler#handleMessage(android.os.Message) */ @Override public void handleMessage(Message msg) { ImageView img; if (msg.what == 0) { List list = (List) msg.obj; Bitmap bitmap = (Bitmap) list.get(0); img = (ImageView) ((Reference<ImageView>) list.get(1)).get(); // if (list.get(1)!=null) { // img = (ImageView) ((Reference<ImageView>)list.get(1)).get(); // // }else { // //img = (ImageView) list.get(2); // } // ImageView img = (ImageView) ((Reference<ImageView>) // list.get(1)).get(); if (img != null) { img.setImageBitmap(bitmap); } } super.handleMessage(msg); } }; 法克我发现跟Gallery有关你拖动图片滚动的时候,它又重新请求一次,重新打开连接,重新设置图片,估计是这个问题导致的。把图片下载下来,直接读sd卡,应该就不会出现这个问题了等下试试 100k的图像,解码后比100k大多了800x600分辨率的图像RGB_565加载到内存也937k了你加载图像时可以加载缩略图BitmapFactory.Options.inSampleSize = n;加载时就加载图像的1/n*n。自己根据图像尺寸算个合适的n值如果你把图像放到Gallery中显示,图像再大也不会超过屏幕大小吧。一般屏幕320x480,480x854(800),那就加载时把图像大小不超过480*480,那你就 可以在内存中多缓存几张图片Bitmap了。同时把从网上下载的图像缓存到sd卡上。这样在Gallery的Adapter中加载图像时先从内存找Bitmap,找不到,到sd卡上找下载的图像重新加载,再找不到,就上网上下载, adapter里面这么写非常逊.就算一张图片只有5K,一样OOME出现.我的解决办法是用OnScroll监听,然后批量下载,而不是对GetView每个下载一次.因为这个方法会下载N次.屏幕不断的刷新,不信你Log记录下. 就算是监听Onscroll同样也会下载多次,我的办法是批量下载,下载后再Notify.然后设置标志,下载成功的,下次不要下载,可以缓存图片,下载失败的如果是Filenotfound异常,下次也不需要再下载了.因为服务器始终是找不到东西的.http://phenom.javaeye.com/blog/756994 我是这么处理的,可以参考下. JNI如何调用第三方SO库,再生成新的SO库 Android Widget 动画 效果 大家看看我这个地图移动的效果是怎么回事?哪里的问题? 请教高手一个问题! Droid-Stock 炒股软件 如何从我的应用程序中关闭 刚才 调出来的setting android下的html5问题 求大神帮我解答,android用红外,怎么遥控设备 请问关于主线程发信息给 子线程通信的问题 android 8以后framelayout问题 初学android 不知如如何入手 如何取得本地地址,并在地图上标出来。
如果是一张的话,那么肯定是会outofmemery的。
vm 肯定不够用的。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
final ImageView imgView = new ImageView(imgContext);
imgView.setLayoutParams(new Gallery.LayoutParams(209, 123));// 设置布局图片大小
// imgvView.setClickable(true);//
imgView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);//
imgView.setBackgroundColor(0xFFFFFF);
imgView.setPadding(5, 5, 5, 5);// 设置边框间距
imgView.setAdjustViewBounds(true);// 保持图片高宽比
// imgvView.setImageBitmap(urlarr[position]);// 设置图片源
final WeakReference<ImageView> imageViewReference = new WeakReference<ImageView>(
imgView);
final URL tempUrl = urlarr[position]; new Thread() {
public void run() {
try {
Message msg = new Message(); msg.what = 0;
HttpURLConnection urlcon = (HttpURLConnection) tempUrl
.openConnection();
urlcon.setDoInput(true);
urlcon.connect();
InputStream is = urlcon.getInputStream();
Bitmap tempBitmap = BitmapFactory.decodeStream(is); List<Object> myList = new ArrayList<Object>();
myList.add(tempBitmap); myList.add(imageViewReference);
// myList.add(imgView);
// imgvView.setImageBitmap(tempBitmap);
msg.obj = myList;
is.close();
imghHandler.sendMessage(msg); } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start(); return imgView;
} Handler imghHandler = new Handler() { /*
* (non-Javadoc)
*
* @see android.os.Handler#handleMessage(android.os.Message)
*/
@Override
public void handleMessage(Message msg) {
ImageView img;
if (msg.what == 0) {
List list = (List) msg.obj;
Bitmap bitmap = (Bitmap) list.get(0); img = (ImageView) ((Reference<ImageView>) list.get(1)).get(); // if (list.get(1)!=null) {
// img = (ImageView) ((Reference<ImageView>)list.get(1)).get();
//
// }else {
// //img = (ImageView) list.get(2);
// } // ImageView img = (ImageView) ((Reference<ImageView>)
// list.get(1)).get();
if (img != null) {
img.setImageBitmap(bitmap);
} }
super.handleMessage(msg);
} };
我发现跟Gallery有关
你拖动图片滚动的时候,它又重新请求一次,重新打开连接,重新设置图片,估计是这个问题导致的。
把图片下载下来,直接读sd卡,应该就不会出现这个问题了
等下试试
800x600分辨率的图像RGB_565加载到内存也937k了
你加载图像时可以加载缩略图
BitmapFactory.Options.inSampleSize = n;
加载时就加载图像的1/n*n。
自己根据图像尺寸算个合适的n值
如果你把图像放到Gallery中显示,图像再大也不会超过屏幕大小吧。
一般屏幕320x480,480x854(800),那就加载时把图像大小不超过480*480,那你就 可以在内存中多缓存几张图片Bitmap了。同时把从网上下载的图像缓存到sd卡上。
这样在Gallery的Adapter中加载图像时先从内存找Bitmap,找不到,到sd卡上找下载的图像重新加载,再找不到,就上网上下载,
就算一张图片只有5K,一样OOME出现.我的解决办法是用OnScroll监听,然后批量下载,而不是对GetView每个下载一次.因为这个方法会下载N次.屏幕不断的刷新,不信你Log记录下.
然后设置标志,下载成功的,下次不要下载,可以缓存图片,下载失败的如果是Filenotfound异常,下次也不需要再下载了.因为服务器始终是找不到东西的.http://phenom.javaeye.com/blog/756994 我是这么处理的,可以参考下.