从服务端读取图片地址放入自定义viewPaper中不显示图片

Android 码拜 9年前 (2015-09-29) 1026次浏览
在服务端读取图片的地址放入自定义的ViewPaper中,总是加载不出来图片,因为服务端读取的是xml文件才能取出图片路径,然后读取xml文件的操作必须在线程中执行,所以加载图片的操作也就在线程中,下面是读取服务端图片名字的代码

public void cate1(){
		new Thread(new Runnable() {
			@Override
			public void run() {
				
				AboutService ab = new AboutService();
				InputStream stream2;
				stream2 = HttpUtil.GetInputStreamFromURL(URL+"pic.xml");
				
				try {
					imgList = ab.getImages(stream2);
				
					for (int i = 1; i < imgList.size(); i++) {
						stringList.add(imgList.get(i).getPicImg().toString());
					}
					Looper.prepare();
					for (int j = 0; j < stringList.size(); j++) {
						String path = imgUrl + stringList.get(j);
						ImageView image = new ImageView(getApplicationContext());
						asyImg.LoadImage(path, image);      //缓存加载图片
						listViews.add(image);
					}
					//这里就是往自定义viewpaper中赋值操作
					myPager.start(AboutUsActivity.this, listViews, 0, ovalLayout,
		    				R.layout.ad_bottom_item, R.id.ad_item_v,
		    				R.drawable.dot_focused, R.drawable.dot_normal);
		        	Looper.loop();
				} catch (Exception e) {
					e.printStackTrace();
				}
				/*Message msg=new Message();
				msg.what = 1;
				hand.sendMessage(msg);*/
			}
		}).start();
	}

下面是缓存加载图片

public class AsyncImageLoader {
    // 为了加快速度,在内存中开启缓存(主要应用于重复图片较多时,或者同一个图片要多次被访问,比如在ListView时来回滚动)
    public Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();
    private ExecutorService executorService = Executors.newFixedThreadPool(5); // 固定五个线程来执行任务
    private final Handler handler = new Handler();
    // SD卡上图片储存地址
    private final String path = Environment.getExternalStorageDirectory()
            .getPath() + "/maiduo";
 
    /**
     *
     * @param imageUrl
     *            图像url地址
     * @param callback
     *            回调接口
     * @return 返回内存中缓存的图像,第一次加载返回null
     */
    public Drawable loadDrawable(final String imageUrl,
            final ImageCallback callback) {
        // 如果缓存过就从缓存中取出数据
        if (imageCache.containsKey(imageUrl)) {
            SoftReference<Drawable> softReference = imageCache.get(imageUrl);
            if (softReference.get() != null) {
                return softReference.get();
            }
        } else if (useTheImage(imageUrl) != null) {
            return useTheImage(imageUrl);
        }
        // 缓存中没有图像,则从网络上取出数据,并将取出的数据缓存到内存中
        executorService.submit(new Runnable() {
            public void run() {
                try {
                    final Drawable drawable = Drawable.createFromStream(
                            new URL(imageUrl).openStream(), "image.png");
                    imageCache.put(imageUrl, new SoftReference<Drawable>(
                            drawable));
                    handler.post(new Runnable() {
                        public void run() {
                            callback.imageLoaded(drawable);
                        }
                    });
                    saveFile(drawable, imageUrl);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        });
        return null;
    }
 
    // 从网络上取数据方法
    public Drawable loadImageFromUrl(String imageUrl) {
        try {
 
            return Drawable.createFromStream(new URL(imageUrl).openStream(),
                    "image.png");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
 
    // 对外界开放的回调接口
    public interface ImageCallback {
        // 注意 此方法是用来设置目标对象的图像资源
        public void imageLoaded(Drawable imageDrawable);
    }
 
    // 引入线程池,并引入内存缓存功能,并对外部调用封装了接口,简化调用过程
    public void LoadImage(final String url, final ImageView iv) {
        if (iv.getImageMatrix() == null) {
            iv.setImageResource(R.drawable.door);
        }
        // 如果缓存过就会从缓存中取出图像,ImageCallback接口中方法也不会被执行
        Drawable cacheImage = loadDrawable(url,
                new AsyncImageLoader.ImageCallback() {
                    // 请参见实现:如果第一次加载url时下面方法会执行
                    public void imageLoaded(Drawable imageDrawable) {
                        iv.setImageDrawable(imageDrawable);
                    }
                });
        if (cacheImage != null) {
            iv.setImageDrawable(cacheImage);
        }
    }
 
    /**
     * 保存图片到SD卡上
     *
     * @param bm
     * @param fileName
     *
     */
    public void saveFile(Drawable dw, String url) {
        try {
            BitmapDrawable bd = (BitmapDrawable) dw;
            Bitmap bm = bd.getBitmap();
 
            // 获得文件名字
            final String fileNa = url.substring(url.lastIndexOf("/") + 1,
                    url.length()).toLowerCase();
            File file = new File(path + "/image/" + fileNa);
            // 创建图片缓存文件夹
            boolean sdCardExist = Environment.getExternalStorageState().equals(
                    android.os.Environment.MEDIA_MOUNTED); // 判断sd卡是否存在
            if (sdCardExist) {
                File maiduo = new File(path);
                File ad = new File(path + "/image");
                // 如果文件夹不存在
                if (!maiduo.exists()) {
                    // 按照指定的路径创建文件夹
                    maiduo.mkdir();
                    // 如果文件夹不存在
                } else if (!ad.exists()) {
                    // 按照指定的路径创建文件夹
                    ad.mkdir();
                }
                // 检查图片是否存在
                if (!file.exists()) {
                    file.createNewFile();
                }
            }
 
            BufferedOutputStream bos = new BufferedOutputStream(
                    new FileOutputStream(file));
            bm.compress(Bitmap.CompressFormat.JPEG, 100, bos);
            bos.flush();
            bos.close();
        } catch (Exception e) {
            // TODO: handle exception
        }
    }
 
    /**
     * 使用SD卡上的图片
     *
     */
    public Drawable useTheImage(String imageUrl) {
 
        Bitmap bmpDefaultPic = null;
 
        // 获得文件路径
        String imageSDCardPath = path
                + "/image/"
                + imageUrl.substring(imageUrl.lastIndexOf("/") + 1,
                        imageUrl.length()).toLowerCase();
        File file = new File(imageSDCardPath);
        // 检查图片是否存在
        if (!file.exists()) {
            return null;
        }
        bmpDefaultPic = BitmapFactory.decodeFile(imageSDCardPath, null);
 
        if (bmpDefaultPic != null || bmpDefaultPic.toString().length() > 3) {
            Drawable drawable = new BitmapDrawable(bmpDefaultPic);
            return drawable;
        } else
            return null;
    }
 
}
方案推荐指数:15
非ui线程不能更新ui,你可以在数据获取完毕后发送handler,在Handler更新ui
方案推荐指数:15
首先要确定是从url下载不成功还是没刷新,5s后还没有得到这个图片加载后返回相关的状态,程序自然就ANR了,需要分析一下trace log
方案推荐指数:10
线程不能更新UI

用handle+message回传数据更新UI

另外,不允许用框架吗?推荐picasso 不过没试过xml文件是否可行


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明从服务端读取图片地址放入自定义viewPaper中不显示图片
喜欢 (0)
[1034331897@qq.com]
分享 (0)