You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android如何从JSON链接为ImageView设置图片?附onPostExecute代码示例

在Android中从JSON接口加载图片到ImageView的正确姿势

嘿,我看到你在手动处理从JSON接口获取图片链接并设置到ImageView的逻辑,先给你提个醒:你当前的代码有个关键问题——onPostExecute(主线程)里直接执行new URL(poster).getContent()这种网络操作,会阻塞UI线程,很容易引发ANR(应用无响应),这可是Android开发的大忌。

另外,手动实现还得自己处理缓存、异常、图片压缩等细节,成本很高。下面给你两种靠谱的解决方案:

方案一:使用成熟的图片加载库(推荐)

像Glide、Picasso这类第三方库已经帮我们封装好了异步加载、缓存、错误处理、图片优化等所有细节,代码简洁又可靠。

以Glide为例:

  1. 首先在Module级别的build.gradle中添加依赖:
dependencies {
    implementation 'com.github.bumptech.glide:glide:4.16.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'
}
  1. 修改你的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

火山引擎 最新活动