I have a problem with generic method's explicit type arguments. I know I can do this:
Foo.<Bar>function();
assuming there is a
void <T> function() {...}
function in Foo class. The exact problem is:
I would like to download some content (Android with Ion)
These contents are similar (Article, BlogArticle, ...), all implements a ContentItem interface
At the moment the downloading looks like this:
news for example
private void downloadNews() {
Ion.with(this)
.load(URL_NEWS)
.as(new TypeToken<List<Article>>(){})
.setCallback(new FutureCallback<List<Article>>() {
@Override
public void onCompleted(Exception e, List<Article> result) {
// do something with result
}
});
}
If I want to download blog articles, I have to change url and Article class only (for BlogArticle).
I tried to make a generic function like this:
private <T extends ContentItem> void download(String url) {
Ion.with(this)
.load(url)
.as(new TypeToken<List<T>>(){})
.setCallback(new FutureCallback<List<T>>() {
@Override
public void onCompleted(Exception e, List<T> result) {
// do something with result
}
});
}
and call that function
this.<Article>download(url);
It's ok, compile fine. After running I get
java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to com.my.packagename.model.ContentItem
The problem is that it doesn't use the explicit class for mapping Json to pojo.
Can you suggest me a generic solution?
Years later, but I thought it can be useful for someone. I ended up with a simpler solution. It's just a simple, truncated version but you can get the idea:
public static <T> void asList(Context context, String url, Class<T[]> clazz, final FutureCallback<List<T>> callback) {
Ion.with(context)
.load(url)
.as(clazz)
.setCallback(new FutureCallback<T[]>() {
@Override
public void onCompleted(Exception e, T[] result) {
callback.onCompleted(e, Arrays.asList(result));
}
});
}
And use like:
asList(context, url, YourObject[].class, new FutureCallback<List<YourObject>>() {...});