android - 尝试使用 Picasso 库加载图像。无法获取上下文

标签 android picasso android-context

在我的代码中,我使用 ImageView 项目填充 RecyclerView,这些项目将保存从在线数据库中拍摄的一些照片。
当需要在布局上显示时,我的应用程序将自动调用我的 PosterViewHolder 子类的 bind() 函数以用数据填充 ImageView。

为了从数据库中检索这些图像,我设置了一个名为 ShowPoster 的 ASyncTask。 ShowPoster 被设置为 PosterViewHolder 的子类,它允许我引用我试图填充的 ImageView。

我的 ASyncTask 在单独的字符串上执行,允许我在不中断主 UI 线程的情况下使用网络功能(这在 Android 中是强制性的)。

从数据库中检索原始 JSON 并对其进行适当解析后,我得到了 imageURL,这是我将从数据库中提取的图像的 URL。

然后我使用 Picasso 库从数据库中检索图像,并将图像加载到我的名为 posterView 的 ImageView 中,使用以下特定代码行:

Picasso.with(this).load(imageURL).into(posterView);

这是我的错误发生的地方,特别是在 .with(this) 的参数中,我需要在其中提供我的应用程序的上下文。

我曾尝试用函数调用替换 this 以获取应用程序上下文,例如 Context.getApplicationContext(),但在此类中,我似乎无法调用这些函数。

我还尝试在我的主 Activity 的 onCreate() 函数中实例化一个新的 Context,然后将它传递给我的 PosterAdapter 类的构造函数,这样我就可以在我的 ASyncTask 中引用它而无需进行任何函数调用,它偷偷经过 IDE 并编译,但应用程序在运行时崩溃。

在寻求解决我的问题的过程中,我偶然发现有人提到 AndroidManifest 中没有 android:name="" 与问题有关,但我并不完全确保在包名称之外在此字段中放置什么。

作为引用,这是我的代码和 list

代码:(完整重新发布,API key 已审查)

package com.example.android.myapplication;

import android.content.Context;
import android.os.AsyncTask;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.squareup.picasso.Picasso;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

public class PosterAdapter extends RecyclerView.Adapter<PosterAdapter.PosterViewHolder>{
    private String POPULAR_MOVIES_URL = "https://api.themoviedb.org/3/movie/popular?api_key=XXXX";
    private String RATED_MOVIES_URL = "https://api.themoviedb.org/3/movie/top_rated?api_key=XXXX";
    private String searchQueryURL;
    private int mNumberItems;
    private MovieDBJSONTools mJSONTools;

    public PosterAdapter(int numItems, String query){
        mNumberItems = numItems;
        mJSONTools = new MovieDBJSONTools();
        searchQueryURL = null;
        switch(query){
            case "popular":
                searchQueryURL = POPULAR_MOVIES_URL;
                break;
            case "rating":
                searchQueryURL = RATED_MOVIES_URL;
                break;
        }
    }

    @Override
    public PosterViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType){
        Context context = viewGroup.getContext();
        int layoutIdForListItem = R.layout.poster_item;
        LayoutInflater inflater = LayoutInflater.from(context);
        boolean shouldAttachToParentImmediately = false;

        View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
        PosterViewHolder viewHolder = new PosterViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(PosterViewHolder viewHolder, int position){
            viewHolder.bind(position);
    }

    @Override
    public int getItemCount(){
        return mNumberItems;
    }

     class PosterViewHolder extends RecyclerView.ViewHolder{
        ImageView posterView;

        public PosterViewHolder(View itemView) {
            super(itemView);

            posterView = (ImageView) itemView.findViewById(R.id.poster_item);
        }

        void bind(int pos){
            new ShowPoster().execute(pos);
        }

        private class ShowPoster extends AsyncTask<Integer, Void, Void>{
            @Override
            protected Void doInBackground(Integer... params) {
                try {
                    String rawJSON = getResponseFromHttpURL(new URL(searchQueryURL));
                    String imageURL = mJSONTools.GetMoviePosterURL(rawJSON, params[0]);
                    Picasso.with(this).load(imageURL).into(posterView);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
            }
        }
    }

    private String getResponseFromHttpURL(URL url) throws IOException {
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        try {
            InputStream in = urlConnection.getInputStream();

            Scanner scanner = new Scanner(in);
            scanner.useDelimiter("\\A");

            boolean hasInput = scanner.hasNext();
            if (hasInput) {
                String next = scanner.next();
                return next;
            } else {
                return null;
            }
        } finally {
            urlConnection.disconnect();
        }
    }
}

list :

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.myapplication">
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="Popular Movies"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

最佳答案

将 Context 声明为全局的。然后在构造函数中赋值

private class PosterViewHolder extends RecyclerView.ViewHolder{
ImageView posterView;
Context context;

    public PosterViewHolder(View itemView) {
    super(itemView);

    posterView = (ImageView) itemView.findViewById(R.id.poster_item);
    context = itemView.getContext();
    }

然后使用picasso中的context

 Picasso.with(context).load(imageURL).into(posterView);

关于android - 尝试使用 Picasso 库加载图像。无法获取上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42640827/

相关文章:

Android:限制 Android Market 中支持的设备

android - 为什么 JSONObject(jsonString) 构造函数在我的 Android 应用程序中抛出异常?

android - 如何设置 Picasso 占位符 scaleType?

java - 从微调器选择中获取适配器或对象值

android - 如何测试 IntentService android?

android - 带有 Picasso 和支持库的 Android 2.2 中的 ImageView 旋转无法正常工作

android - picasso 加载在 AsyncTask 中生成的图像

Android:从 BroadcastReceiver 事件发送 LocalBroadcastManager 的 Intent

android - 在 Toast .maketext() 方法中使用 getApplicationcontext() 和 this 有什么区别

Android:一个 Activity 可以有两个或多个类吗?