您好,欢迎来到华佗小知识。
搜索
您的当前位置:首页Android 下载网络图片注意的问题

Android 下载网络图片注意的问题

来源:华佗小知识


很多时候我们从网络上获取图片,但有时图片路径明明正确,却要出错。图片小无所谓,图片大了就出错了。

ImageView imageView = new ImageView(context);

URL url = new URL(\"图片路径\");

URLConnection conn = url.openConnection();

conn.connect();

InputStream is = conn.getInputStream();

BitmapFactory.Options options=new BitmapFactory.Options();

options.inSampleSize = 10;

originalImage = BitmapFactory.decodeStream(is,null,options);

imageView.setImageBitmap(bitmapWithReflection);

这样问题就可以解决了

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

在使用的过程中,如果网络比较慢的话,则会出现下载不成功的问题。经过google搜索,终于解决了这个问题。

一般我们会用以下的代码:

java代码:

//获取connection,方法略

conn = getURLConnection(url);

is = conn.getInputStream();

//获取Bitmap的引用

Bitmap bitmap = BitmapFactory.decodeStream(is)

但是网络不好的时候获取不了图片,推荐使用以下的方法:

java代码:

//获取长度

int length = (int) conn.getContentLength();

if (length != -1) {

byte[] imgData = new byte[length];

byte[] temp=new byte[512];

int readLen=0;

int destPos=0;

while((readLen=is.read(temp))>0){

System.arraycopy(temp, 0, imgData, destPos, readLen);

destPos+=readLen;

}

bitmap=BitmapFactory.decodeByteArray(imgData, 0, imgData.length);

}

使用上面的方法的好处是在网速不好的情况下也会将图片数据全部下载,然后在进行解码,生成图片对象的引用,所以可以保证只要图片存在都可以下载下来。当然在读取图片数据的时候也可用java.nio.ByteBuffer,这样在读取数据前就不用知道图片数据的长度也就是图片的大小了,避免了有时候 http获取的length不准确,并且不用做数组的copy工作。

java代码:

public synchronized Bitmap getBitMap(Context c, String url) {

URL myFileUrl = null;

Bitmap bitmap = null;

try {

myFileUrl = new URL(url);

} catch (MalformedURLException e) {

bitmap = BitmapFactory.decodeResource(c.getResources(),

com.jixuzou.moko.R.drawable.defaultimg);

return bitmap;

}

try {

HttpURLConnection myFileUrl.openConnection();

conn = (HttpURLConnection)

conn.setDoInput(true);

conn.connect();

InputStream is = conn.getInputStream();

int length = (int) conn.getContentLength();

if (length != -1) {

byte[] imgData = new byte[length];

byte[] temp = new byte[512];

int readLen = 0;

int destPos = 0;

while ((readLen = is.read(temp)) > 0) {

System.arraycopy(temp, 0, imgData, destPos, readLen);

destPos += readLen;

}

bitmap = BitmapFactory.decodeByteArray(imgData, 0,imgData.length);

}

} catch (IOException e) {

bitmap =

BitmapFactory.decodeResource(c.getResources(),com.jixuzou.moko.R.drawable.defaultimg);

return bitmap;

}

return bitmap;

}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

从网络获取图片,数据为InputStream流对象,然后调用BitmapFactory的decodeStream()方法解码获取图片。代码如下:

private Bitmap getUrlBitmap(String url)

{

Bitmap bm;

try{

URL imageUrl=new URL(url);

HttpURLConnection conn=(HttpURLConnection)imageUrl.openConnection();

conn.connect();

InputStream is=conn.getInputStream();

//byte[] bt=getBytes(is); //注释部分换用另外一种方式解码

//bm=BitmapFactory.decodeByteArray(bt,0,bt.length);

bm=BitmapFactory.decodeStream(is); //如果采用这种解码方式在低版本的API上会出现解码问题

is.close();

conn.disconnect();

return bm;

}

catch(MalformedURLException e)

{

e.printStackTrace();

}

catch (IOException e)

{

e.printStackTrace();

}

return null;

}

结果在运行时编译器提示: DEBUG/skia(xxx): --- decoder->decode returned false

已经确定从网络获取的数据流没有出现问题,而是在图片解码时出现错误。上网查找了不少资料,也没有得出确切的原因,不过有几条意见值得关注。

一种说法是在android 较低版本的api中会有不少内部的错误,我的代码运行时选择2.1API Level 7和2.2API Level 8都会出现这个问题,而选择2.3 API Level 9后能够正常解码图片。

我的另外一种做法是换用别的解码方式对图片解码,见代码中被注释的那俩行,使用decodeByteArray()方法在低版本的API上也能够正常解码,解决了这个问题。

其中getBytes(InputStream is)是将InputStream对象转换为Byte[]的方法,具体代码如下:

private byte[] getBytes(InputStream is) throws IOException {

ByteArrayOutputStream baos = new ByteArrayOutputStream();

byte[] b = new byte[1024];

int len = 0;

while ((len = is.read(b, 0, 1024)) != -1)

{

baos.write(b, 0, len);

baos.flush();

}

byte[] bytes = baos.toByteArray();

return bytes;

}

private void queuePhoto(String url, Activity activity, ImageView imageView)

002 {

003 // This ImageView may be used for other images before. So there may be

004 // some old tasks in the queue. We need to discard them.

005

006 photosQueue.Clean(imageView);

007 PhotoToLoad p = new PhotoToLoad(url, imageView);

008

009 synchronized (photosQueue.photosToLoad)

010 {

011 photosQueue.photosToLoad.push(p);

012 photosQueue.photosToLoad.notifyAll();

013 }

014

015 // start thread if it's not started yet

016 if (photoLoaderThread.getState() == Thread.State.NEW)

017 photoLoaderThread.start();

018 }

019

020 public Bitmap getBitmap(String url)

021 {

022 try

023 {

024 // I identify images by hashcode. Not a perfect solution, good for the

025 // demo.

026 027 028

029 030 031 032 033

034 035 String filename = String.valueOf(url.hashCode());

File f = new File(cacheDir, filename);

// from SD cache

Bitmap b = decodeFile(f);

if (b != null)

return b;

// from web

try {

036 Bitmap bitmap = null;

037 if(!url.equals(\"\")){

038 InputStream is = new URL(url).openStream();

039 040 041 042 043 044 045 046 047 048 OutputStream os = new FileOutputStream(f);

Utils.CopyStream(is, os);

os.close();

bitmap = decodeFile(f);

}

return bitmap;

}

catch (Exception ex)

{

ex.printStackTrace();

049 return null;

050 }

051 }

052 catch(Exception e)

053 {

054 e.printStackTrace();

055

056 return null;

057 }

058 }

059

060 /*decodes image and scales it to reduce memory consumption

061 * @param file path

062 * @throws FileNotFoundException

063 * @return bitmap

0 * */

065 066 067 068

069 070 071 072 073 074 o);

Bitmap b = null;

try {

useThisBitmap = null;

//Decode image size

BitmapFactory.Options o = new BitmapFactory.Options();

o.inJustDecodeBounds = true;

final int IMAGE_MAX_SIZE = 70;

BitmapFactory.decodeStream(new FileInputStream(f), null, private Bitmap decodeFile(File f){

075 int scale = 2;

076 if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {

077 scale = 2 ^ (int) Math.ceil(Math.log(IMAGE_MAX_SIZE / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5));

078 }

079

080 //Decode with inSampleSize

081 BitmapFactory.Options o2 = new BitmapFactory.Options();

082

083 o2.inSampleSize = scale;

084 b = BitmapFactory.decodeStream(new FileInputStream(f), null, o2);

085 useThisBitmap = b;

086

087 }

088 catch (FileNotFoundException e) {

0 }

090 091 092 093 094 095 096 097 098 099 }

catch(Exception e)

{

e.printStackTrace();

}

finally

{

System.gc();

}

return useThisBitmap;

100

101

102 // Task for the queue

103 private class PhotoToLoad

104 {

105 public String url;

106 public ImageView imageView;

107

108 public PhotoToLoad(String u, ImageView i) {

109 url = u;

110 imageView = i;

111 }

112 }

113

114 private PhotosQueue photosQueue = new PhotosQueue();

115

116

117

118 // stores list of photos to download

119 private class PhotosQueue

120 {

121 private Stack photosToLoad Stack();

122 // removes all instances of this ImageView

123 private void Clean(ImageView image)

124 {

125 for (int j = 0; j < photosToLoad.size();)

new

=

126 {

127 if (photosToLoad.get(j).imageView == image)

128 photosToLoad.remove(j);

129 else

130 ++j;

131 }

132 }

133 }

134

135 private class PhotosLoader extends Thread

136 {

137 public void run()

138 {

139 try

140 {

141 while (true)

142 143 the

144 145 146 147 148 149 150 151 {

// thread waits until there are any images to load in // queue

if (photosQueue.photosToLoad.size() == 0)

synchronized (photosQueue.photosToLoad) {

photosQueue.photosToLoad.wait();

}

if (photosQueue.photosToLoad.size() != 0) {

PhotoToLoad photoToLoad;

synchronized (photosQueue.photosToLoad) {

152 photoToLoad photosQueue.photosToLoad.pop();

=

153 }

154 Bitmap bmp = getBitmap(photoToLoad.url);

155 156 157 158 BitmapDisplayer(bmp,

159 160 photoToLoad.imageView

161 162 163 cache.put(photoToLoad.url, bmp);

if (((String) photoToLoad.imageView.getTag())

.equals(photoToLoad.url)) {

BitmapDisplayer bd = new

photoToLoad.imageView);

Activity a = (Activity)

.getContext();

a.runOnUiThread(bd);

}

1 }

165 if (Thread.interrupted())

166 break;

167 }

168 } catch (InterruptedException e) {

169 // allow thread to exit

170 }

171 }

172 }

173

174 private PhotosLoader photoLoaderThread = new PhotosLoader();

175

176 // Used to display bitmap in the UI thread

177 private class BitmapDisplayer implements Runnable

178 {

179 private Bitmap bitmap;

180 private ImageView imageView;

181

182 private BitmapDisplayer(Bitmap b, ImageView i)

183 {

184 bitmap = b;

185 imageView = i;

186 }

187

188 public void run()

1 {

190 if (bitmap != null)

191 imageView.setImageBitmap(bitmap);

192 }

193 }

194

195 public void stopThread()

196 {

197 photoLoaderThread.interrupt();

198 }

199

200 public void clearCache()

201 {

202 cache.clear();

203 File[] files = cacheDir.listFiles();

204 for (File f : files)

205 f.delete();

206 207 }

}

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo0.cn 版权所有 湘ICP备2023017654号-2

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务