Class Cast Exception,来自AsyncTask的Adapter

时间:2014-09-30 15:00:51

标签: java android interface

我在尝试使用适配器内的java.lang.ClassCastExceptionInterface时收到AsyncTask。我不知道这是否是允许的,但我不明白为什么只要一切都保持在上下文中它就不会存在。

当我尝试使用自定义Fragment设置GridView时,代码会从Adapter开始。

mSceneGridAdapter = new SceneGridAdapter(getActivity(), mScenesList);

这导致我的SceneGridAdapter类被调用

public class SceneGridAdapter extends BaseAdapter implements HandleProductThumbnail {
    private Context mContext;
    private ArrayList<Scene> mSceneList = null;
    private LayoutInflater mInflater;
    private Drawable mThumbnail;

    public SceneGridAdapter() {}

    public SceneGridAdapter(Context context, ArrayList<Scene> sceneList) {
        super();

        mContext = context;
        if (mSceneList != null) {
            clearData();
        } else {
            mSceneList = sceneList;
        }

        mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.scene_cell, null);
        }

        ImageView sceneView = (ImageView) convertView.findViewById(R.id.sceneImage);

        Scene scene = mSceneList.get(position);
        String specifier = scene.getSpecifier() + "/" + scene.getName();
        LoadScenes scenes = new LoadScenes(mContext, specifier);
        scenes.execute();
        sceneView.setBackground(mThumbnail);

        return convertView;

    }

    @Override
    public int getCount() {
        return mSceneList.size();
    }

    @Override
    public Object getItem(int position) {
        return mSceneList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    public void clearData() {
        mSceneList.clear();
    }

    @Override
    public void handleProductThumbnail(Drawable thumb) {
        mThumbnail = thumb;
    }
}

实现了我的Interface HandleProductThumbnails

public interface HandleProductThumbnail {
        void handleProductThumbnail(Drawable thumb);
}

然后调用名为LoadScenes的AsyncTask加载器类,它加载缩略图并将它们返回给适配器。

public class LoadScenes extends AsyncTask<Void, Void, Drawable> {
    private static final String LOADING = "Loading...";
    private static final String PNG = "_ORIGINAL.PNG";

    private Context mContext;
    private HandleProductThumbnail mHandleThumbnail = null;
    private ProgressDialog mProgressDialog;
    private String mSpecifier;

    public LoadScenes () {}

    public LoadScenes (Context context, String specifier) {
        mContext = context;
        mSpecifier = specifier;
    }

    @Override
    public void onPreExecute() {
        mProgressDialog = new ProgressDialog(mContext);
        mProgressDialog.setMessage(LOADING);
        mProgressDialog.show();
    }

    public Drawable doInBackground(Void... v) {
        Drawable productThumbnail = getDrawable(mSpecifier);
        return productThumbnail;
    }

    public void onPostExecute(Drawable productThumbnail) {
        mProgressDialog.dismiss();
        mHandleThumbnail = (HandleProductThumbnail) mContext;
        mHandleThumbnail.handleProductThumbnail(productThumbnail);
    }

    public Drawable getDrawable(String specifier) {
        Bitmap bmp = null;
        Drawable productThumbnail = null;
        specifier = specifier.replace("\\", "/") + PNG;
        try {
            bmp = BitmapFactory.decodeStream(mContext.getAssets().open(specifier));
            if (bmp != null) {
                int width = 300;
                int height = 240;
                bmp = Bitmap.createScaledBitmap(bmp, width, height, true);
                productThumbnail = new BitmapDrawable(mContext.getResources(), bmp);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return productThumbnail;
    }
}

最后是我的日志

09-30 10:34:35.725: E/AndroidRuntime(22442): java.lang.ClassCastException: com.example.xxx.visualizer.VisualizerActivity cannot be cast to com.example.xxx.interfaces.HandleProductThumbnail
09-30 10:34:35.725: E/AndroidRuntime(22442):    at com.example.xxx.visualizer.LoadScenes.onPostExecute(LoadScenes.java:46)

Fragment附加到名为VisualizerActivity的Activity,所有传递的上下文都来自Activity。虽然这个问题有点分层,但代码是相当的样板。我想知道我是否只是做了一些不允许的事情?根据我对Context的理解,这应该有效。请让我知道我做错了什么,为什么,以及是否可以解决。谢谢

3 个答案:

答案 0 :(得分:1)

您的活动似乎没有实现HandleProductThumbnail,而是您的自定义适配器。在你的情况下,我宁愿为AsyncTask子类添加一个方法而不是强制转换:

   public void setHandleProductThumbnail(HandleProductThumbnail listener) {
           mHandleThumbnail = listener;
   }

OnPostExecute

 public void onPostExecute(Drawable productThumbnail) {
    mProgressDialog.dismiss();
    if (mHandleThumbnail != null)
       mHandleThumbnail.handleProductThumbnail(productThumbnail);
}

答案 1 :(得分:0)

你的问题在这里:

mHandleThumbnail = (HandleProductThumbnail) mContext;

您将mContext投射到HandleProductThumbnail,而mContextContext,因此未实现您的自定义界面。如果需要对HandleProductThumbnail的引用,请将其作为构造函数参数传递。

最后注意:如果您尝试在每个列表项上加载缩略图,我建议使用Picasso,这样可以让您更加轻松。

答案 2 :(得分:0)

很明显,它会创建一个类强制转换异常, 因为mContext是你的活动对象,它没有实现“HandleProductThumbnail”接口。

虽然您通过正确转换来纠正您的代码,但由于适配器中的代码行数不足而导致错误

    LoadScenes scenes = new LoadScenes(mContext, specifier);
    scenes.execute();
    sceneView.setBackground(mThumbnail);

因为第二行是异步调用而mThumbnail是null。您可以在运行时应用另一种方法从URL渲染图像。