onPostExecute clash when using AsyncTask - android - java

I can't understand what is happening here. The ide throws this message onPostExecute(Bitmap)' in 'Anonymous class derived from android.os.AsyncTask' clashes with 'onPostExecute(Result)' in 'android.os.AsyncTask'; attempting to use incompatible return type:
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final View[] v = {convertView};
final Bitmap[] mBitmap = new Bitmap[1];
final Object that = this.resources;
View view = new AsyncTask<Void, Void, Bitmap>() {
protected Bitmap doInBackground(Void... args) {
try {
mBitmap[0] = drawableFromUrl(activity.getString(R.string.test_url));
} catch (IOException e) {
e.printStackTrace();
}
return mBitmap[0];
}
#Override
protected View onPostExecute(Bitmap mBitmap) {
Drawable d = new BitmapDrawable((Resources) that, mBitmap);
final Feed item = feed_items.get(position);
if (v[0] == null) {
LayoutInflater vi =
(LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v[0] = vi.inflate(R.layout.grid_item, null);
}
if (item != null) {
v[0].findViewById(R.id.v1).setBackground(d);
v[0].findViewById(R.id.v2).setBackground(d);
}
return v[0];
}
}.execute((Void) null);
return view;
}

I assume you are using getView() in a custom adapater.
But you can't return from an onPostExecute(), so try to inflate the view right away.
Setup the AsyncTask to download the BPM and update the view, but return it normally from getView() even though the data isn't there yet. Once the Async completes it will be there.
public View getView(final int position, View convertView, ViewGroup parent) {
View v1 = convertView;
final Bitmap[] mBitmap = new Bitmap[1];
final Object that = this.resources;
final View v;
if (v1 == null) {
LayoutInflater vi =
(LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.grid_item, null);
}
else {
v = v1;
}
new AsyncTask<Void, Void, Bitmap>() {
protected Bitmap doInBackground(Void... args) {
try {
mBitmap[0] = drawableFromUrl(activity.getString(R.string.test_url));
} catch (IOException e) {
e.printStackTrace();
}
return mBitmap[0];
}
#Override
protected void onPostExecute(Bitmap mBitmap) {
Drawable d = new BitmapDrawable((Resources) that, mBitmap);
final Feed item = feed_items.get(position);
v.findViewById(R.id.v1).setBackground(d);
v.findViewById(R.id.v2).setBackground(d);
}
}.execute((Void) null);
return v;
}

The return type from onPostExecute should be void.
See: http://developer.android.com/reference/android/os/AsyncTask.html#onPostExecute%28Result%29

Related

Get Value in method from getView of BaseAdapter

This is my Custom Adapter. I have three ImageViews here. I wanted to give onclick for every imageview.
First I have called a method when click on ImageView. In that method I need to replace with the another image. And also need to replace remaining two Imageview images also.
Now When I click on first imageview, method is calling and image also changing for that. But for Remaining two Imageviews, It is showing NULL POINTER EXCEPTION.
How to access those ImageViews in that method.
Any help would be appreciated.
public class CustomTestingProductsListAdapter extends BaseAdapter{
public CustomTestingProductsListAdapter(Context context, Activity activity, List<V_APP_PACK_QR_DET_INFO> pack_qr_det_infos) {
layoutInFlater = LayoutInflater.from(context);
this.pack_qr_det_infos = pack_qr_det_infos;
this.curActivity = activity;
this.mContext = (VilanApplication) VilanApplication.mContext;
}
#Override
public int getCount() {
return pack_qr_det_infos.size();
}
#Override
public Object getItem(int position) {
return pack_qr_det_infos.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
try{
CustomTestingProductsListAdapter.ViewHolder holder;
if(convertView == null){
holder = new CustomTestingProductsListAdapter.ViewHolder();
convertView = layoutInFlater.inflate(R.layout.tst_ver_prdouct_list_items,null);
holder.tvProduct = convertView.findViewById(R.id.tv_qc_productName);
holder.DLSno = convertView.findViewById(R.id.tvtst_DLSno);
holder.iv_tst_received = convertView.findViewById(R.id.iv_tst_received);
holder.iv_tst_not_received = convertView.findViewById(R.id.iv_tst_not_received);
holder.iv_tst_wrong_product = convertView.findViewById(R.id.iv_tst_wrong_product);
convertView.setTag(holder);
}else{
holder = (CustomTestingProductsListAdapter.ViewHolder) convertView.getTag();
}
holder.DLSno.setText(pack_qr_det_infos.get(position).PRODUCTSLNO);
holder.iv_tst_received.setOnClickListener(onClickListener(position));
}catch (Exception e){
Log.d(VilanConstants.TAG,"/Excp #listAdp"+ e.toString());
}
return convertView;
}
private View.OnClickListener onClickListener(final int position){
return new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
CustomTestingProductsListAdapter.ViewHolder holder;
holder = new CustomTestingProductsListAdapter.ViewHolder();
holder.iv_tst_received = v.findViewById(R.id.iv_tst_received);
holder.iv_tst_not_received = v.findViewById(R.id.iv_tst_not_received);
holder.iv_tst_wrong_product = v.findViewById(R.id.iv_tst_wrong_product);
Toast.makeText(mContext, "Item Received" , Toast.LENGTH_SHORT).show();
holder.iv_tst_received.setImageResource(R.drawable.ic_received_green);
holder.iv_tst_not_received.setImageResource(R.drawable.ic_not_received);
holder.iv_tst_wrong_product.setImageResource(R.drawable.ic_wrong_product);
Status = 0 ;
}catch (Exception e){
Log.e(VilanConstants.TAG,"/Excp due to"+e.toString());
}
}
};
}
public class ViewHolder{
private TextView tvProduct;
private TextView DLSno;
private ImageView iv_tst_received;
private ImageView iv_tst_not_received;
private ImageView iv_tst_wrong_product;
}
}
Update Your getView():
#Override
public View getView(int position, View convertView, ViewGroup parent) {
try{
CustomTestingProductsListAdapter.ViewHolder holder;
if(convertView == null){
holder = new CustomTestingProductsListAdapter.ViewHolder();
convertView = layoutInFlater.inflate(R.layout.tst_ver_prdouct_list_items,null);
holder.tvProduct = convertView.findViewById(R.id.tv_qc_productName);
holder.DLSno = convertView.findViewById(R.id.tvtst_DLSno);
holder.iv_tst_received = convertView.findViewById(R.id.iv_tst_received);
holder.iv_tst_not_received = convertView.findViewById(R.id.iv_tst_not_received);
holder.iv_tst_wrong_product = convertView.findViewById(R.id.iv_tst_wrong_product);
convertView.setTag(holder);
}else{
holder = (CustomTestingProductsListAdapter.ViewHolder) convertView.getTag();
}
holder.DLSno.setText(pack_qr_det_infos.get(position).PRODUCTSLNO);
holder.iv_tst_received.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Toast.makeText(mContext, "Item Received" , Toast.LENGTH_SHORT).show();
holder.iv_tst_received.setImageResource(R.drawable.ic_received_green);
holder.iv_tst_not_received.setImageResource(R.drawable.ic_not_received);
holder.iv_tst_wrong_product.setImageResource(R.drawable.ic_wrong_product);
Status = 0 ;
}
});
}catch (Exception e){
Log.d(VilanConstants.TAG,"/Excp #listAdp"+ e.toString());
}
return convertView;
}

How to fetch an image from a url to an arrayList

I'm trying to show images that are read from a url, they are more than an image so I had to put all of them in an arraylist and then make the images display in a gridview, for some reason it's not showing anything, the gridview is completely blank, please advise what am I doing wrong.
BottomSheetDialog_Smiles.java
Communicator.getInstance().on("subscribe start", new Emitter.Listener() {
#Override
public void call(Object... args) {
try{
JSONDictionary response = (JSONDictionary) args[0];
String str = response.get("emojiPack").toString();
JSONArray emojies = new JSONArray(str);
for(int i=0;i<emojies.length();i++){
JSONObject response2 = (JSONObject)
emojies.getJSONObject(i);
emojiModel = new EmojiModel((String) response2.get("urlFile"));
emojiUrl = emojiModel.getEmojiFile();
Picasso.with(getApplicationContext()).load(emojiUrl);
JSONDictionary t = JSONDictionary.fromString(response2.toString());
emojiModel.init(t);
emojieModels.add(new EmojiModel(emojiUrl));
}
EmojiAdapter emojiAdapter = new EmojiAdapter(getApplicationContext(),
emojieModels);
gridView2.setAdapter(emojiAdapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
EmojiAdapter emojiAdapter = new EmojiAdapter(getApplicationContext(),
emojieModels);
gridView2.setAdapter(emojiAdapter);
EmojiAdapter.java
public class EmojiAdapter extends ArrayAdapter<EmojiModel> {
Context context;
ArrayList<EmojiModel> list = new ArrayList<>();
public EmojiAdapter(Context context,ArrayList<EmojiModel> list) {
super(context, R.layout.smiles_items_layout, list);
this.context = context;
this.list = list;
}
#NonNull
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater o =
(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = o.inflate(R.layout.gifts_layout_2, parent , false);
ImageView imageView = (ImageView) v.findViewById(R.id.smile_image_view);
imageView.setImageResource(Integer.parseInt((list.get(position)).urlFile));
return v;
}
}
EmojiModel.Java
public class EmojiModel {
private int id;
private int price;
public String urlFile;
public EmojiModel(String urlFile) {
this.urlFile=urlFile;
}
public String getEmojiFile() {
return urlFile;
}
public void init(JSONDictionary data){
try{
urlFile = (String) data.get("urlFile");
id = Integer.parseInt((String) data.get("id"));
price = Integer.parseInt((String) data.get("price"));
}catch(Exception e){
e.printStackTrace();
}
}
}
obviously this line of code wont work :
imageView.setImageResource(Integer.parseInt((list.get(position)).urlFile));
instead of that just use glide or piccaso to load pics.
first add this line to your gradle file :
implementation 'com.github.bumptech.glide:glide:4.5.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.5.0'
then instead of above line ,just write :
Glide.with(context).load(list.get(position)).urlFile).into(imageView);
also the picaso library is pretty same
also change your adapter in this way :
public class EmojiAdapter extends BaseAdapter {
Context context;
ArrayList<EmojiModel> list = new ArrayList<>();
public EmojiAdapter(Context context,ArrayList<EmojiModel> list) {
super(context, R.layout.smiles_items_layout, list);
this.context = context;
this.list = list;
}
#NonNull
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater o =
(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = o.inflate(R.layout.gifts_layout_2, parent , false);
ImageView imageView = (ImageView) v.findViewById(R.id.smile_image_view);
imageView.setImageResource(Integer.parseInt((list.get(position)).urlFile));
return v;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return position;
}
}
Use Picasso in Adapter to show image
#NonNull
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater o =
(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = o.inflate(R.layout.gifts_layout_2, parent , false);
ImageView imageView = (ImageView) v.findViewById(R.id.smile_image_view);
Picasso.with(getApplicationContext()).load(list.get(position).getEmojiUrl()).into(imageView);
return v;
}
}

How to get data from AsyncTask in android?

Iv tried some on the solutions in stack overflow, but was not able to work it out for my case.
I want to get the Bitmap data from onPostExecute or bmp from doInBackground and set it to ImageView imageurl using imageurl.setImageBitmap() in the getView() method
public class BooksAdapter extends ArrayAdapter<Books> {
public BooksAdapter(Activity context, ArrayList<Books> word) {
super(context, 0, word);
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
// Check if the existing view is being reused, otherwise inflate the view
View listItemView = convertView;
if (listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(
R.layout.list_item, parent, false);
}
// Get the {#link AndroidFlavor} object located at this position in the list
Books currentbook = getItem(position);
TextView bookView = (TextView) listItemView.findViewById(R.id.bookTittle);
String booktitle = currentbook.getBookName();
bookView.setText(booktitle);
TextView authorView = (TextView) listItemView.findViewById(R.id.authorname);
String authorname = currentbook.getAuthorName();
authorView.setText(authorname);
ImageView imageurl = (ImageView) listItemView.findViewById(R.id.imageView);
String imagelink = currentbook.getImageLink();
ImageAsyncTask task = new ImageAsyncTask();
task.execute(imagelink);
// imageurl.setImageBitmap();
return listItemView;
}
private class ImageAsyncTask extends AsyncTask<String, Void, Bitmap> {
#Override
protected Bitmap doInBackground(String... urls) {
URL url = null;
Bitmap bmp = null;
try {
url = new URL(urls[0]);
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "Error with creating URL ", e);
}
try {
bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
} catch (IOException e) {
Log.e(LOG_TAG, "Problem retrieving the earthquake JSON results.", e);
}
return bmp;
}
#Override
protected void onPostExecute(Bitmap data) {
}
}
}
Just pass your ImageView to AsyncTask via constructor and then set image in onPostExecute like this:
ImageAsyncTask task = new ImageAsyncTask(myImageView);
private class ImageAsyncTask extends AsyncTask<String, Void, Bitmap> {
private ImageView img;
ImageAsyncTask(Imageview img){
this.img = img;
}
...
protected void onPostExecute(Bitmap data) {
this.img.setImageBitmap(data);
}

The ListView skips the bitmap images in the 2nd and 3rd rows. How to populate all the rows?

The problem is that the getView() method is skipping to view the other images, in short, getView() only displays the 1st and last row of the ListView.
How to populate all the rows in the ListView?
This is my getView() code in my CustomListAdapter, there is no URL included.
I just directly download the images from the API.
public View getView(int position, View convertView, ViewGroup parent) {
RowItemLoyalty rowItem = getItem(position);
if (inflater == null) {
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_item, null);
holder = new Holder();
holder.title = (TextView) convertView.findViewById(R.id.description);
holder.exp = (TextView) convertView.findViewById(R.id.promotion_expiration);
holder.tokensFor = (TextView) convertView.findViewById(R.id.tokensForRedeemOffer);
holder.promotionImages = (ImageView) convertView.findViewById(R.id.promotion_image);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
holder.title.setText(rowItem.getDescription());
holder.exp.setText(rowItem.getDateEnd());
holder.tokensFor.setText(rowItem.getTokensFor());
//holder.promotionImages.setImageBitmap(rowItem.getImage1());
try {
image_id.put(ConstantKeys.ID, rowItem.getImageId());
} catch (JSONException e) {
e.printStackTrace();
}
ImageDownloadRequest2 request = new ImageDownloadRequest2();
SharedPreferences sharedPreferences = context.getSharedPreferences("USERPASS", 0);
String email = sharedPreferences.getString("username", null);
String password = sharedPreferences.getString("password", null);
request.getToken(email, password, new ApiRequestListener() {
#Override
public void onSuccess(Object object) {
(new GetImageTask() {
#Override
protected void onPostExecute(Bitmap data) {
super.onPostExecute(data);
if (data != null) {
Bitmap[] holderImage = new Bitmap[] {data};
holder.promotionImages.setImageBitmap(holderImage[0]);
Log.d("BITMAPVALUE", String.valueOf(data));
}else
{
holder.promotionImages.setImageResource(R.drawable.app_icon);
}
}
}).execute();
}
#Override
public void onError(String error) {
Log.e("Get Logo", error);
}
});
Log.d("IMAGESTASHLOYALTY", String.valueOf(rowItem.getImageId()));
return convertView;
}
And this is my AsyncTask
private static class GetImageTask extends AsyncTask<Void, Void, Bitmap>
{
#Override
protected Bitmap doInBackground(Void... params)
{
ImageDownload2 manager = ImageDownload2.getInstance();
Bitmap result = null;
try
{
result = manager.apiCall("File/DownloadFiles", image_id.toString(), "C");
}
catch (Exception e)
{
e.printStackTrace();
}
return result;
}
}
Standard misconcept of recycling the views. You give the AsyncTask the holder as parameter. But holder will be a different holder by the time the asynctask is ready with downloading the image.
You better give int position as parameter to the AsyncTask as then you can place the image at the rigth position.

ListView displays arraylist data twice

Can anyone help me with figuring out why my listview repeats the results it gets from the database. I am using a Listview with Checkbox. Here is my code below.
public class AccessLevels extends Fragment {
MyAdminAdapter adminAdapter = null;
Guards guards;
ListView listView;
public ArrayList<Guards> guardsName;
public String str_name;
public boolean isAdmin;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_access_levels, container, false);
listView = (ListView)view.findViewById(R.id.list_of_guards);
return view;
}
private class MyAdminAdapter extends ArrayAdapter<Guards>{
private ArrayList<Guards> objectsList;
public MyAdminAdapter(Context context, int resource, ArrayList<Guards> objectsList) {
super(context, resource, objectsList);
this.objectsList = objectsList;
this.objectsList.addAll(objectsList);
}
private class ViewHolder{
CheckBox chk_name;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null){
LayoutInflater vi = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.single_row_access, null);
holder = new ViewHolder();
holder.chk_name = (CheckBox) convertView.findViewById(R.id.chk_guard);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
final Guards guards = objectsList.get(position);
holder.chk_name.setText(guards.getName());
holder.chk_name.setChecked(guards.isChecked());
holder.chk_name.setTag(guards);
holder.chk_name.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
Guards guards = (Guards) cb.getTag();
guards.setChecked(cb.isChecked());
}
});
return convertView;
}
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onDetach() {
super.onDetach();
}
}
I get the data an store it like this.
private void DisplayAllNames() {
guardsName = new ArrayList<Guards>();
ParseQuery<ParseObject> guardsQuery = ParseQuery.getQuery("Guards");
guardsQuery.whereExists("Name");
guardsQuery.orderByAscending("Name");
guardsQuery.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> list, ParseException e) {
if (e == null) {
if (list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
ParseObject data = list.get(i);
str_name = data.getString("Name");
isAdmin = data.getBoolean("admin");
guards = new Guards(str_name, isAdmin);
guardsName.add(guards);
}
adminAdapter = new MyAdminAdapter(getActivity(), R.layout.single_row_access, guardsName);
listView.setAdapter(adminAdapter);
} else {
}
} else {
}
}
});
}
Thanks in advance.
Remove this line from your MyAdminAdapter's constructor:
this.objectsList.addAll(objectsList);
You are already adding your items in the previous instruction:
this.objectsList = objectsList;
In your MyAdminAdapter you are adding the data twice:
this.objectsList = objectsList;
this.objectsList.addAll(objectsList);
You just have to remove the second line.

Categories

Resources