如何实现getStreamFromPOtherSource()处理异常?解决UIL空协议支持问题
你遇到的这个问题确实是因为NewsAPI返回的部分新闻图片URI存在异常(比如直接是null字符串,或者格式不符合UIL的协议识别规则),导致UIL把它当成了一个名为null的协议来处理,而默认的BaseImageDownloader并不支持这个协议,所以抛出了异常。下面给你几个递进的解决方案:
第一步:提前过滤无效图片URL(最省心的前置处理)
在你把数据填充到Adapter之前,先对每个新闻的图片URL做校验。如果URL是null、空字符串,或者直接是"null"这个字符串,就直接给ImageView设置默认占位图,根本不用让UIL去加载无效的地址:String imageUrl = newsItem.getImageUrl(); DisplayImageOptions options = new DisplayImageOptions.Builder() .showImageOnLoading(R.drawable.default_placeholder) .build(); if (imageUrl == null || imageUrl.trim().isEmpty() || imageUrl.equalsIgnoreCase("null")) { imageLoader.displayImage("drawable://" + R.drawable.default_news_image, imageView, options); } else { imageLoader.displayImage(imageUrl, imageView, options); }这里用
drawable://协议是UIL原生支持的,可以直接加载本地drawable资源。第二步:自定义ImageDownloader处理[null]协议(兜底方案)
如果担心还有漏网的无效URL,可以自定义一个ImageDownloader继承自BaseImageDownloader,重写getStreamFromOtherSource方法来专门处理null协议的情况:public class NullSafeImageDownloader extends BaseImageDownloader { private final Context mContext; public NullSafeImageDownloader(Context context) { super(context); mContext = context; } @Override protected InputStream getStreamFromOtherSource(String imageUri, Object extra) throws IOException { // 识别并处理null协议的URI if (imageUri.startsWith("null://")) { // 返回默认图片的输入流 return mContext.getResources().openRawResource(R.drawable.default_news_image); } // 其他未知协议交给父类处理 return super.getStreamFromOtherSource(imageUri, extra); } }然后在初始化UIL的时候,把这个自定义Downloader配置进去:
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext()) .imageDownloader(new NullSafeImageDownloader(getApplicationContext())) // 其他你的配置项,比如内存缓存、磁盘缓存等 .build(); ImageLoader.getInstance().init(config);这样即使有UIL识别为
null://的URI,也会自动加载默认图片,不会抛出异常。第三步:在JSON解析阶段提前处理(从源头避免问题)
你还可以在解析NewsAPI返回的JSON数据时,就把无效的图片URL替换成一个统一的标识(比如null://default),这样后续Adapter和UIL的处理会更统一:JSONObject newsJson = ...; // 从NewsAPI获取的单条新闻JSON String imageUrl = newsJson.optString("urlToImage"); // 校验并替换无效URL if (imageUrl == null || imageUrl.equals("null") || imageUrl.trim().isEmpty()) { imageUrl = "null://default"; } NewsItem newsItem = new NewsItem(); newsItem.setImageUrl(imageUrl);
按照这个流程处理,基本就能解决你遇到的图片加载异常问题了。
内容的提问来源于stack exchange,提问作者OmegaKi113r

