Android AsyncTask will not work downloading image - android

I am hoping someone can help me with a problem I have been having. I am in the process of making my app work on versions greater than 3.0 so I can only perform GUI tasks on the UI Thread. I have got the following code, I am getting no compile errors but it is not working. In the log I get the following error:
I/AndroidRuntime(464): NOTE: attach of thread 'Binder Thread #3' failed
Thank you for your help!
new DownloadImageTask().execute(imgURL); //imgURL is declared as string URL
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
protected void onPostExecute(Bitmap result) {
((ImageView) findViewById(R.id.imgCity)).setImageBitmap(bmp);
}
protected Bitmap doInBackground(String... params) {
return loadImage(params[0]);
}
}
public Bitmap loadImage(String poiURLimg) {
try {
URL ulrn = new URL(poiURLimg);
HttpURLConnection con = (HttpURLConnection) ulrn.openConnection();
InputStream is = con.getInputStream();
bmp = BitmapFactory.decodeStream(is);
if (null != bmp)
return bmp;
} catch (Exception e) {
}
return bmp;
}

The Binder Thread #3 error is not related to the code in your app. There are a number of potential causes usually related to something in eclipse. You can read this post which gives some examples.
As to why the Bitmap wont load - in your onPostExecute you are setting the Bitmap for that ImageView to bmp. Bmp is name of the value that your loadImage method creating the bitmap returns. It is not the name of the Bitmap you pass as an argument into onPosExecute - that is Bitmap result. Change bmp to result and it should work.

A couple things to try. First, make sure you've added the INTERNET permission to your AndroidManifest.xml file. You'll need that to download images from the internet and your app will crash without it (although it doesn't sound like this is your issue)
Try using this for your loadImage() method:
public static Bitmap loadImage(String src)
{
try
{
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
}
catch (IOException e)
{
e.printStackTrace();
return null;
}
}
Here is an example of a DownloadImageTask that I wrote and use in my apps currently (so I know it works correctly):
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap>
{
#Override
protected Bitmap doInBackground(String... params)
{
return loadImage(params[0]);
}
#Override
protected void onPostExecute(Bitmap result)
{
if (isCancelled() || result == null)
return;
((ImageView) findViewById(R.id.image_view)).setImageBitmap(result);
}
}

Related

How can I convert an AsyncTask to a Runnable?

I want to set bitmap for ImageView. I have the URL from Firebase stroage, I use the BitmapFactory to turn to picture, I need to apply it on ImageView, I can do it with AsyncTask but I don't know how to did it with thread or runnable.
AsyncTask cannot use anymore in Android API 30, after I find on Internet, I find a solution that is run with thread and runnable.
These are my code that can work with AsyncTask:
AsyncTask<Void,Void,Bitmap> work = new AsyncTask<Void, Void, Bitmap>() {
#Override
protected Bitmap doInBackground(Void... voids) {
URL url = null;
try {
url = new URL("Some URL");
} catch (MalformedURLException e) {
Log.d("Error",e.toString());
}
Bitmap bmp = null;
try {
bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
} catch (IOException e) {
Log.d("Error",e.toString());
}
return bmp;
}
#Override
protected void onPostExecute(Bitmap bmp){
imageMessage.setImageBitmap(bmp);
}
};
work.execute();
I try to do it with thread and runnable but I don't know after I docode, how do I sent and apply it on ImageView. In AsyncTask, I can do that.

Display Images in Recyclerview without using any library [duplicate]

I'm trying to download an image using a URL and a button in my app. When I'm running it on my phone, I,m not able to download the image. Can anyone please point out the problem with this. Thanks for the help in advance :)
This is my code.
public class MainActivity extends AppCompatActivity {
ImageView download;
public void downloadImage(View view){
DownloadImage image = new DownloadImage();
Bitmap result;
try {
result = image.execute("https://en.wikipedia.org/wiki/File:Bart_Simpson_200px.png").get();
download.setImageBitmap(result);
}
catch(Exception e)
{
e.printStackTrace();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
download = (ImageView) findViewById(R.id.imageView);
}
public class DownloadImage extends AsyncTask<String, Void, Bitmap>{
#Override
protected Bitmap doInBackground(String... urls) {
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL(urls[0]);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoInput(true);
urlConnection.connect();
InputStream in = urlConnection.getInputStream();
Bitmap Image = BitmapFactory.decodeStream(in);
in.close();
return Image;
}
catch (MalformedURLException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
}
you can download image from url in two ways
1.you can user Glide library to load image from url look the below code it can help you in simple way
compile this library
implementation 'com.github.bumptech.glide:glide:4.6.1'
than load image like this
Glide.with(MainActivity.this)
.load(url)
.apply(new RequestOptions().placeholder(R.drawable.booked_circle).error(R.drawable.booked_circle))
.into(imageview);
2 .try this if you dont want to use third party library
new DownloadImage(imamgeview).execute(url);
create a Async Task
public class DownloadImage extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImage(ImageView bmImage) {
this.bmImage = (ImageView ) 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.d("Error", e.getStackTrace().toString());
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
i hope that it will work in your case
You did not call the function
downloadImage(view);
In the oncreate (after the findviewbyid line)
Also check if the internet permision is in the Android Manifest file :
<uses-permission android:name="android.permission.INTERNET" />
Having said that you should use a library like Glide\Picasso\Ion etc... much better than asynctask for this purpuse
https://github.com/bumptech/glide - Glide
https://github.com/koush/ion - Ion
http://square.github.io/picasso/ - picasso
Hope it helped.

Convert URL to Bitmap results in a network error in Android

I'm trying to load an image from an URL to a Bitmap but I am getting a NetworkOnMainThreadException error but I don't know why.
This is the method I am using:
public Bitmap getBitmapFromURL(String src) {
try {
java.net.URL url = new java.net.URL(src);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
I also tried to load the image to a Target using Picasso library, because in the end, I want to get the dominant color from this image using Palette. This is the code I have using Picasso:
Picasso.with(MovieDetails.this)
.load("https://image.tmdb.org/t/p/w500" + backdrop)
.into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
Palette palette = Palette.from(bitmap).generate();
System.out.println(palette.getVibrantSwatch().toString().substring(16, Math.min(palette.getVibrantSwatch().toString().length(), 22)));
LinearLayout lLayout = (LinearLayout) findViewById(R.id.layout_bg);
lLayout.setBackgroundColor(Color.parseColor("#"+ palette.getVibrantSwatch().toString().substring(16, Math.min(palette.getVibrantSwatch().toString().length(), 22))));
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
I put this inside my onCreate method, but I am getting "method does not override method from its superclass" errors in all the three #Override methods.
I managed to solve my problem by using an AsyncTask as it follows:
I put this in the end of my Activity:
public class MyAsync extends AsyncTask<Void, Void, Bitmap>{
#Override
protected Bitmap doInBackground(Void... params) {
try {
URL url = new URL("https://image.tmdb.org/t/p/w500" + backdrop);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
Please note that inside this method I put the URL for the image.
To access the Bitmap inside my Activity and get the dominant color using Palette I did this:
MyAsync obj = new MyAsync(){
#Override
protected void onPostExecute(Bitmap bmp) {
super.onPostExecute(bmp);
Bitmap bm = bmp;
if (bm != null && !bm.isRecycled()) {
Palette palette = Palette.from(bm).generate();
System.out.println(palette.getVibrantSwatch().toString().substring(16, Math.min(palette.getVibrantSwatch().toString().length(), 22)));
LinearLayout lLayout = (LinearLayout) findViewById(R.id.layout_bg);
lLayout.setBackgroundColor(Color.parseColor("#"+ palette.getVibrantSwatch().toString().substring(16, Math.min(palette.getVibrantSwatch().toString().length(), 22))));
}
}
};
obj.execute();
This code is inside my onCreate method.
The way to correct the first issue is to perform that action in a Thread or Runnable, There is a flag you can set something like StrictModeEnabled or something like that, but that's bad, don't resort to that.
As far as picasso, i dont know about the overriding methods from superclass thing, i'd try to do it in onViewCreated instead of onCreate

task.execute url to bitmap mismatch

public class MainActivity extends Activity {
ImageView downloadedimg;
public class ImageDownloader extends AsyncTask<String,void,Bitmap> {
#Override
protected Bitmap doInBackground(String... urls) {
try{
URL url=new URL(urls[0]);
HttpURLConnection connection=(HttpURLConnection) url.openConnection();
connection.connect();
InputStream inputStream=connection.getInputStream();
Bitmap mybitmap= BitmapFactory.decodeStream(inputStream);
return mybitmap;
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
}
public void downloadImage(View view) {
ImageDownloader task = new ImageDownloader;
Bitmap myImage;
try {
myImage = task.execute("https://www.google.co.in/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&cad=rja&uact=8&ved=0ahUKEwiOw5HvydXOAhVKqo8KHYHfAtIQjRwIBw&url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FBart_Simpson&psig=AFQjCNFZSwEG2tjp15Km14uuzEsmZUZ_MQ&ust=1471974330385306");
downloadedimg.setImageBitmap(myImage);
}
catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
downloadedimg=(ImageView)findViewById(R.id.imageView);
}
in the line
myImage = task.execute("some url to image address online");
the complier shows error that
incompatible type
required: android.graphics.Bitmap
found: android.os.AsyncTask "<"java.lang.String,void,android.graphics.Bitmap>
double code infront of java's bracket are not part of statement
#edit Thank you for previous advice i searched and found .get() method
i used task("").get() to return the bitmap image and code compiled without errors but now nothings happens when i click the download image button
AsyncTask.execute does not return the object downloaded. It can't, the entire idea of an AsyncTask is that its asynchronous. Any code that needs to use the result should either be put in onPostExecute (for UI changes) or at the end of doInBackground (for processing data).

Image downloading via multithreading not working in Android

I have to download an image from a url and then show the downloaded image in a imageview on the UI.
For this i am using the code mentioned below:
public class ShowUIData extends AsyncTask<Void, Void, Void> {
String productvalues[];
Drawable productimagebitmap;
#Override
protected Void doInBackground(Void... params) {
productvalues = hb.getProductDetailsWithJson(id + 1);
if (productvalues != null) {
productimagebitmap = getImage(productvalues[3]);
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (productvalues != null) {
// Set the values obtained from the database.
// Check if image returned from URL is not null.
if (productimagebitmap != null) {
ImageView productimage = (ImageView) findViewById(R.id.productimage);
productimage.setImageDrawable(productimagebitmap);
}
}
dismissDialog();
}
// Download image from URL obtained for database.
private Drawable getImage(String address) {
try {
Log.i("product details", "starting image download");
URL url = new URL(address);
URLConnection conn = url.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
Drawable d = Drawable.createFromStream(is, "src name");
is.close();
return d;
} catch (Exception e) {
Log.i("the url", address);
e.printStackTrace();
return getApplicationContext().getResources().getDrawable(
R.drawable.noimage);
}
}
A valid URL is being passed to the getImage function and no exception is being thrown , still the image is not being set on the imageview. When i debug my application, then the image is setting properly.
I believe i need to put a blocking call until the image is download and then call image.setImageDrawable.
What is the problem occuring over here. I am not able to figure out why i am not able to load any images and why only when i debug , i see an image?
thank you in advance.
you should try this example. It runtime fetches images from the url and also displays it in listview. I think this will help you.
Non UI thread can't update UI component. Use handler to update UI component.

Categories

Resources