Reputation: 703
I am getting a java.lang.ClassCastException
when trying to use an Interface
and an AsyncTask
from inside my adapter. I don't know if this is 'allowed', but I can't see why it wouldn't be as long as everything is kept in context.
The code starts in my Fragment
when I try and set my GridView
with a custom Adapter
.
mSceneGridAdapter = new SceneGridAdapter(getActivity(), mScenesList);
Which leads to my SceneGridAdapter class being called
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;
}
}
Which implements my Interface
HandleProductThumbnails
public interface HandleProductThumbnail {
void handleProductThumbnail(Drawable thumb);
}
and then calls my AsyncTask
loader class called LoadScenes, which loads the thumbnails and returns them to the adapter.
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;
}
}
and finally my log
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)
The Fragment
is attached to an Activity
called VisualizerActivity, and all the context being passed comes from that Activity
. While this problem is somewhat layered, the code is fairly boilerplate. I was wondering if I am just doing something that isn't allowed? From my understanding of Context
this should work. Please let me know what I'm doing wrong, why, and if it can be fixed. Thank you
Upvotes: 2
Views: 346
Reputation: 99
It is clearly visible that it would create an class cast exception, because mContext is your activity`s object which is not implementing the "HandleProductThumbnail" interface.
Though you rectify your code by right casting, yet it will produce error due to below lines of code in your adapter
LoadScenes scenes = new LoadScenes(mContext, specifier);
scenes.execute();
sceneView.setBackground(mThumbnail);
Because second line is an async call and mThumbnail would be null.You may apply another approach for rendering images from URL at run time.
Upvotes: 0
Reputation: 157437
Looks like your activity is not implementing the HandleProductThumbnail
, but your custom adapter. In your case, instead of casting, I would rather add a method to the AsyncTask
subclass:
public void setHandleProductThumbnail(HandleProductThumbnail listener) {
mHandleThumbnail = listener;
}
and inside OnPostExecute
public void onPostExecute(Drawable productThumbnail) {
mProgressDialog.dismiss();
if (mHandleThumbnail != null)
mHandleThumbnail.handleProductThumbnail(productThumbnail);
}
Upvotes: 1
Reputation: 8629
Your problem is here :
mHandleThumbnail = (HandleProductThumbnail) mContext;
You're casting mContext
to HandleProductThumbnail
whereas mContext
is a Context
, hence not implementing your custom interface. If you need a reference to the HandleProductThumbnail
, pass it as a constructor argument.
Last note : if you're trying to load thumbnails on every list item, I would suggest the use of Picasso, which would make all this much simpler for you.
Upvotes: 0