请看看我这个异步加载图片哪里不对?

oO桀骜 2012-03-23 01:36:02
我在网上找到的一个讲解异步加载图片的例子,照着他的代码我改成这样,可是总是得不到图片,总提示bitmap = null,报空指针错误。是不是和里面的回调接口有关?这个回调接口我也不明白,指点下?逻辑我这个是没问题的,就是不知道怎么就是得不到bitmap资源。上代码。大家看看。帮个忙。


这个是传入url然后判断是否缓存里面有,没有的话从网络下载并加入缓存:代码如下:

import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;

public class TileCheck {
public Map<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>();

private ExecutorService executorService = Executors.newFixedThreadPool(12); // 固定12个线程来执行任务
private final Handler handler = new Handler();
public Bitmap checkLoadBitmap(final String Url,final ImageCallback callback) {
// 如果缓存过就从缓存中取出数据
if (imageCache.containsKey(Url)) {
SoftReference<Bitmap> softReference = imageCache.get(Url);
if (softReference.get() != null) {
return softReference.get();
}
}
// 缓存中没有图像,则从网络上取出数据,并将取出的数据缓存到内存中
executorService.submit(new Runnable() {
public void run() {
try {

final Bitmap bitmap = loadImageFromUrl(Url);

// tileLoader.setBitmap(drawingTile);
// Bitmap bitmap = drawingTile.getBitmap();

imageCache.put(Url, new SoftReference<Bitmap>(bitmap));

handler.post( new Runnable() {
public void run() {
callback.imageLoaded(bitmap);
}
});
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
});
return null;
}
// 从网络上取数据方法
private Bitmap loadImageFromUrl(String strURL) throws IOException {
URL url = new URL(strURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setConnectTimeout(1000);
conn.setRequestMethod("GET");
conn.connect();
for (int i = 0; i < 1; i++) {
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream is = conn.getInputStream();
Bitmap bm = BitmapFactory.decodeStream(is, null, null);
if (is != null) {
is.close();
is = null;
}
if (conn != null) {
conn.disconnect();
conn = null;
}
return bm;
}
}
return null;
}
// protected Bitmap loadImageFromUrl(String Url) {
// try {
//
//// TileLoader tileLoader = new TileLoader(TileLayer);
//
//
//
// return Drawable.createFromStream(new URL(Url).openStream(),
// "image.png");
//
// } catch (Exception e) {
// throw new RuntimeException(e);
// }
// }

// 对外界开放的回调接口
public interface ImageCallback {
// 注意 此方法是用来设置目标对象的图像资源
public void imageLoaded(Bitmap bitmap);
}

}




我这边是调用上面的函数获取bitmap并画出来:

String urllll = drawingTile.getTileSrc();
TileCheck tilecheck = new TileCheck();

ImageCallback callback = null;

Bitmap bitmap = tilecheck.checkLoadBitmap(urllll, callback);


// tileLoader.setBitmap(drawingTile);
// Bitmap bitmap = drawingTile.getBitmap();
Point drawPoint = drawingTile.getScreenPos();
canvas.drawBitmap(bitmap, drawPoint.x, drawPoint.y, null);

大牛们,是哪里有问题。?
...全文
161 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
追风筝的孩子 2012-03-30
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 的回复:]
引用 10 楼 的回复:

异步加载你用AsyncTask吧,你写的它都帮你写好了,内部实现原理和你差不多。线程池是静态的。所以可以多次使用无压力


现在在用asynctask 是比我这个封装的好,不过貌似不能多次使用啊~差不多解决了现在,谢谢了啊~
[/Quote]多次使用指的是可以new多个而不用担心线程池过多。。。
oO桀骜 2012-03-30
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

异步加载你用AsyncTask吧,你写的它都帮你写好了,内部实现原理和你差不多。线程池是静态的。所以可以多次使用无压力
[/Quote]

现在在用asynctask 是比我这个封装的好,不过貌似不能多次使用啊~差不多解决了现在,谢谢了啊~
追风筝的孩子 2012-03-30
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 的回复:]
引用 12 楼 的回复:

引用 11 楼 的回复:
引用 10 楼 的回复:

异步加载你用AsyncTask吧,你写的它都帮你写好了,内部实现原理和你差不多。线程池是静态的。所以可以多次使用无压力


现在在用asynctask 是比我这个封装的好,不过貌似不能多次使用啊~差不多解决了现在,谢谢了啊~
多次使用指的是可以new多个而不用担心线程池过多。。。

……
[/Quote]缓存需要得到下载图片的地址,根据地址得到图片名字,之后到本地去查询,有的话就不下载了。。也就是说下载之前判断一下sdcard有木有这张图片
oO桀骜 2012-03-30
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]

引用 11 楼 的回复:
引用 10 楼 的回复:

异步加载你用AsyncTask吧,你写的它都帮你写好了,内部实现原理和你差不多。线程池是静态的。所以可以多次使用无压力


现在在用asynctask 是比我这个封装的好,不过貌似不能多次使用啊~差不多解决了现在,谢谢了啊~
多次使用指的是可以new多个而不用担心线程池过多。。。
[/Quote]、


哦 多线程在后台下载这个已经实现了,现在在想怎么实现缓存到sd卡里面去,这方面大牛你有没有什么代码或者帖子可以给我看看的?
追风筝的孩子 2012-03-28
  • 打赏
  • 举报
回复
异步加载你用AsyncTask吧,你写的它都帮你写好了,内部实现原理和你差不多。线程池是静态的。所以可以多次使用无压力
oO桀骜 2012-03-26
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 a328240784 的回复:]

。。。这代码写得比较蛋疼。不好改= =
[/Quote]
大牛,您的这句话是说我写的代码的习惯不好还是思路不对?给我提个意见我好主意下啊
oO桀骜 2012-03-26
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 a328240784 的回复:]

= =见鬼了,瓦片地图你都能做得出,这玩意你会搞不出吗
[/Quote]
大哥,我学安卓刚1个月,瓦片地图现在为止瓦片都是公司给的切好了的,框架页是公司给的,要我实现给经纬度和zoom然后显示出地图,能拖动什么的,我在这方面还是小白啊。。。。
追风筝的孩子 2012-03-24
  • 打赏
  • 举报
回复
= =见鬼了,瓦片地图你都能做得出,这玩意你会搞不出吗
追风筝的孩子 2012-03-24
  • 打赏
  • 举报
回复
方法改为返回void,然后在回调方法上做操作if (imageCache.containsKey(Url)) {
SoftReference<Bitmap> softReference = imageCache.get(Url);
if (softReference.get() != null) {
callback.imageLoaded(softReference.get());
}else{
executorService.submit(new Runnable() {
public void run() {
try {

final Bitmap bitmap = loadImageFromUrl(Url);

// tileLoader.setBitmap(drawingTile);
// Bitmap bitmap = drawingTile.getBitmap();

imageCache.put(Url, new SoftReference<Bitmap>(bitmap));

handler.post( new Runnable() {
public void run() {
callback.imageLoaded(bitmap);
}
});
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
});

}

}
追风筝的孩子 2012-03-24
  • 打赏
  • 举报
回复
。。。这代码写得比较蛋疼。不好改= =
oO桀骜 2012-03-23
  • 打赏
  • 举报
回复
晕 那个红色没显示出来

主要就是这个代码

public Bitmap imageLoaded(Bitmap bitmap) {
return bitmap;
}
oO桀骜 2012-03-23
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 zhouyongyang621 的回复:]

Bitmap bitmap = tilecheck.checkLoadBitmap(urllll, callback);
这句话只有当本地存在图片时bitmap才不为空

你要实现ImageCallback接口,然后在ImageCallback接口的imageLoaded()方法中才能拿到下载下来的图片
[/Quote]

恩 总是null的原因是你说的这个 可是这个imageloaded()借口就是不知道怎么实现啊,又修改了下代码,下面的代码是在主线程了调用Tilecheck里的方法,实现了imagecallback借口里的imageloaded可是还是不对啊。。。

public void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
for(int index = 0 ; index <= 11 ; index ++){
………
………
String urllll = needdrawbitmap.urlSrc();

Bitmap bitmap = loadBitmap(urllll,index);


Point drawPoint = needdrawbitmap.getScreenPos();
canvas.drawBitmap(bitmap, drawPoint.x, drawPoint.y, null);
}
}


private TileCheck tilecheck = new TileCheck();
// 引入线程池,并引入内存缓存功能,并对外部调用封装了接口,简化调用过程
private Bitmap loadBitmap(final String url,int id) {
// 如果缓存过就会从缓存中取出图像,ImageCallback接口中方法也不会被执行
Bitmap cacheImage = tilecheck.checkLoadBitmap(url, new TileCheck.ImageCallback() {
// 请参见实现:如果第一次加载url时下面方法会执行
public Bitmap imageLoaded(Bitmap bitmap) {
return bitmap;
}

});
// if (cacheImage != null) {
// return cacheImage;
// }
return cacheImage;
}

我知道主要是红色区域的代码问题,可是就不知道怎么改啊,大牛,怎么在红色区域哪里返回能给我得到和返回bitmap呢?
梦_枫 2012-03-23
  • 打赏
  • 举报
回复
Bitmap bitmap = tilecheck.checkLoadBitmap(urllll, callback);
这句话只有当本地存在图片时bitmap才不为空

你要实现ImageCallback接口,然后在ImageCallback接口的imageLoaded()方法中才能拿到下载下来的图片

80,493

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧