How to get data from AsyncTask in android? - java

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);
}

Related

How do i improve my code to load images from remote server more effiecintly without UI lag?

The adapter provides data for a listview. But when you scroll up and down, it shows old images and takes a couple of seconds to finish loading the images. This is true when you open the view for the first time.
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(imageurl);
task.execute(imagelink);
return listItemView;
}
private class ImageAsyncTask extends AsyncTask<String, Void, Bitmap> {
private ImageView img;
ImageAsyncTask(ImageView img) {
this.img = img;
}
#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) {
this.img.setImageBitmap(data);
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
}
I will recomend to use Glide for this task and dont invent bicycle. You can just call GlideApp.with(this).load("http://url.com").into(imageView); and Glide will do all work for you.
Glide with default image if actual image not loaded from the server.
Place this in app.gradle
compile 'com.github.bumptech.glide:glide:3.7.0'
Use it like,
Glide.with(this)
.load("your_image_url")
.listener(new RequestListener<String, GlideDrawable>() {
#Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
e.printStackTrace();
return false;
}
#Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
Log.d("d", "onResourceReady");
return false;
}
})
.error("your_default_image")// placed in drawable
.into("your_target_view");
Hope this helps.
User Picasso best way to display image even you can set default image when image is loading see below example..
Picasso.with(context).load(imageUrl).placeholder(R.drawable.default_image).into(imageView);
compile 'com.squareup.picasso:picasso:2.4.0' just add into build.gradle

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.

Download and set bitmap into list view

I use this code to download and set images from link to an image view
but when i scroll the list view and scroll back to top the images starts to download and clear the first downloaded picture.
I tried to download and save them into a array bitmap then show them but i cant update array bitmap like an array list and show it one by one in list view what can i do ?
class aa extends ArrayAdapter<String> {
public aa() {
super(MainActivity.this, R.layout.home_row, IDS);
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater li = getLayoutInflater();
View row = li.inflate(R.layout.home_row, parent, false);
TextView name=(TextView)row.findViewById(R.id.home_row_name);
ImageView pic=(ImageView)row.findViewById(R.id.home_row_pic);
name.setText(arrayNAME.get(position).toString());
new Download_image(bitmap_PIC,position,pic).execute(PIC[position]);
return (row);
}
}
And here is the download method :
class Download_image extends AsyncTask<String, Void, Bitmap> {
Bitmap[] bitMap;
int position;
ImageView bmImage;
public Download_image(Bitmap[] bitMap,int position,ImageView bmImage) {
this.bitMap = bitMap;
this.position = position;
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bitMap[position]=result;
bmImage.setImageBitmap(bitmap_PIC[position]);
}
}

Output JSON image in listView

I tried uploading an image using JSON. I create a link to image in JSON. Many times I tried to fix my problem, but with no success.
Is there a mistake in my use of DownloadImageTask in My adapter Adapter ?
MainActivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = (ListView) findViewById(R.id.list);
newsList = new ArrayList<News>();
//this is i take json image
new NewsAsynkTask().execute();
}
public class NewsAsynkTask extends AsyncTask<String , Void, String> {
protected String doInBackground(String... params) {
//code
}
protected void onPostExecute(String file_url) {
pDialog.dismiss();
//this i run adapter
NewsAdapter adapter = new NewsAdapter(getApplicationContext(), R.layout.list_row, newsList);
list.setAdapter(adapter);
}
}
My adapter Adapter
public class NewsAdapter extends ArrayAdapter<News> {
ArrayList<News> ArrayListNews;
int Resourse;
Context context;
LayoutInflater vi;
public NewsAdapter(Context context, int resource, ArrayList<News> objects) {
super(context, resource, objects);
ArrayListNews = objects;
Resourse = resource;
this.context = context;
vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = vi.inflate(Resourse, null);
holder = new ViewHolder();
holder.imageview = (ImageView) convertView.findViewById(R.id.imagenews);
holder.nameNews = (TextView) convertView.findViewById(R.id.namenews);
holder.dayNews = (TextView) convertView.findViewById(R.id.daynews);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
new DownloadImageTask(holder.imageview).execute(ArrayListNews.get(position).getImageNews());
holder.nameNews.setText(ArrayListNews.get(position).getNameNews());
holder.dayNews.setText(ArrayListNews.get(position).getDayNews());
return convertView;
}
static class ViewHolder {
public ImageView imageview;
public TextView nameNews;
public TextView dayNews;
}
//this is i try load image. I using wrong somthing, please help me
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
ImageLoader imgLoader;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
#Override
protected Bitmap doInBackground(String... urls) {
final String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
Handler handler = new Handler(context.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
//this is class on this [link][1]. I try use simple, it work. But here dont work
imgLoader = new ImageLoader(context);
imgLoader.DisplayImage(urldisplay, bmImage);
}
});
} catch (Exception e) {
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
}

Custom adapter for ListView (only 1 ImageView being displayed)

For some reason my custom adapter is only allowing me to have 1 image visible in the list view at any time, I am not sure why this is happening. There should be a image within each list item but only the last list item has its image set, so I assume I am re-using a value somewhere that I should not be. The rest of the list items are being set properly.
public class CustomAdapter extends ArrayAdapter<Item> {
private ArrayList<Item> itemList;
private ViewHolder holder;
private Context context;
public CustomAdapter(Context context, int textViewResourceId, ArrayList<Item> list) {
super(context, textViewResourceId, list);
this.itemList = new ArrayList<Item>();
this.itemList.addAll(list);
this.context = context;
}
private class ViewHolder {
ImageView img;
TextView name;
CheckBox access;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.list_grid, null);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.access = (CheckBox) convertView.findViewById(R.id.checkBox1);
holder.img = (ImageView) convertView.findViewById(R.id.imageView1);
convertView.setTag(holder);
}
else { holder = (ViewHolder) convertView.getTag(); }
Item it = itemList.get(position);
new UrlLookup().execute(it.getUrl());
holder.name.setText(it.getName());
holder.access.setChecked(it.isSelected());
return convertView;
}
//Create an image from the url passed in from the server and display it on the image view
private class UrlLookup extends AsyncTask<String, Integer, String>{
Bitmap bmp;
#Override
protected String doInBackground(String... params){
try {
URL u = new URL(params[0]);
bmp = BitmapFactory.decodeStream(u.openConnection().getInputStream());
} catch (Exception e) { e.printStackTrace(); }
return "Done!";
}
#Override
protected void onPostExecute(String result){
super.onPostExecute(result);
holder.img.setImageBitmap(bmp);
}
}
}
You're forgetting the fact that your holder changes every time a view is visible. So it's normal only the last item has an image.
AsyncTask will take considerably longer to finish than your getView method.
You should pass your ImageView to your AsyncTask:
new UrlLookup().execute(it.getUrl(), holder.img);
To call the AsyncTask
private class UrlLookup extends AsyncTask<Object, Integer, String>{
Bitmap bmp;
ImageView view;
#Override
protected String doInBackground(Object... params){
view = (ImageView) params[1];
try {
URL u = new URL((String)params[0]);
bmp = BitmapFactory.decodeStream(u.openConnection().getInputStream());
} catch (Exception e) { e.printStackTrace(); }
return "Done!";
}
#Override
protected void onPostExecute(String result){
super.onPostExecute(result);
view.setImageBitmap(bmp);
}
}
Now you will have a reference of the ImageView of every row in every AsyncTask.
I would like to point out to you that Koush has a splendid project for doing just what you want:
UrlImageViewHelper

Categories

Resources