Android如何从JSON链接为ImageView设置图片?附onPostExecute代码示例
在Android中从JSON接口加载图片到ImageView的正确姿势
嘿,我看到你在手动处理从JSON接口获取图片链接并设置到ImageView的逻辑,先给你提个醒:你当前的代码有个关键问题——在onPostExecute(主线程)里直接执行new URL(poster).getContent()这种网络操作,会阻塞UI线程,很容易引发ANR(应用无响应),这可是Android开发的大忌。
另外,手动实现还得自己处理缓存、异常、图片压缩等细节,成本很高。下面给你两种靠谱的解决方案:
方案一:使用成熟的图片加载库(推荐)
像Glide、Picasso这类第三方库已经帮我们封装好了异步加载、缓存、错误处理、图片优化等所有细节,代码简洁又可靠。
以Glide为例:
- 首先在Module级别的
build.gradle中添加依赖:
dependencies { implementation 'com.github.bumptech.glide:glide:4.16.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0' }
- 修改你的
onPostExecute代码:
protected void onPostExecute(String s) { super.onPostExecute(s); try { JSONObject jsonObject = new JSONObject(s); String posterUrl = jsonObject.getString("Poster"); String title = jsonObject.getString("Title"); String year = jsonObject.getString("Year"); // 用Glide加载图片到ImageView Glide.with(this) // 这里传入Activity/Fragment的Context即可 .load(posterUrl) .placeholder(R.drawable.placeholder_default) // 加载中的占位图,可选 .error(R.drawable.error_default) // 加载失败时显示的图片,可选 .into(Poster); // 你的ImageView实例 // 设置文本内容 tryText.setText("Title: " + title); movieYear.setText("Year: " + year); } catch (JSONException e) { e.printStackTrace(); // 这里可以添加JSON解析失败的提示逻辑 } }
方案二:手动实现异步加载(不推荐,仅作参考)
如果不想依赖第三方库,你需要把网络操作放到后台线程,再回到主线程更新UI。这里用Executor+Handler的方式(AsyncTask已被弃用,不推荐使用):
protected void onPostExecute(String s) { super.onPostExecute(s); try { JSONObject jsonObject = new JSONObject(s); final String posterUrl = jsonObject.getString("Poster"); String title = jsonObject.getString("Title"); String year = jsonObject.getString("Year"); // 先更新文本内容 tryText.setText("Title: " + title); movieYear.setText("Year: " + year); // 开启后台线程加载图片 ExecutorService executor = Executors.newSingleThreadExecutor(); Handler mainHandler = new Handler(Looper.getMainLooper()); executor.execute(() -> { Drawable loadedDrawable = null; try { InputStream inputStream = new URL(posterUrl).openStream(); loadedDrawable = Drawable.createFromStream(inputStream, "poster_image"); } catch (IOException e) { e.printStackTrace(); } final Drawable finalDrawable = loadedDrawable; // 回到主线程更新ImageView mainHandler.post(() -> { if (finalDrawable != null) { Poster.setImageDrawable(finalDrawable); } else { // 加载失败,设置默认图 Poster.setImageResource(R.drawable.error_default); } }); }); } catch (JSONException e) { e.printStackTrace(); } }
最后提醒:
不管用哪种方式,都别忘了在AndroidManifest.xml中添加网络权限:
<uses-permission android:name="android.permission.INTERNET" />
内容的提问来源于stack exchange,提问作者Liber8




