Reputation: 874
I am trying to get info from a server, including photos. I have created a class called ServerManager
, which allows me to download the desired information. However, I cannot download images with Picasso because I get a java.lang.IllegalStateException: Method call should happen from the main thread.
.
This is what I am doing in ServerManager
:
// Check if the photo is already downloaded
if (!checkInternalPhoto(member)) {
final String outputURL = context.getFilesDir().getAbsolutePath() + "/" + member.photoPath;
String photoURL = rootURL + "photos/" + member.photoPath;
Picasso.with(context)
.load(photoURL)
.into(new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
File file = new File(outputURL);
try {
file.createNewFile();
FileOutputStream outputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG,100,outputStream);
outputStream.flush();
outputStream.close();
} catch (IOException e) {
Log.e("IOException",e.getLocalizedMessage());
}
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
}
What can I do?
Edit: I tried to use the code in my MainActivity and I am getting the same error message...
public void downloadPhotos(List<Member> memberList){
String rootInURL = serverManager.getRootURL();
String rootOutURL = serverManager.getOutputURL();
for(int i = 0; i < memberList.size(); i++){
if(!serverManager.checkInternalPhoto(memberList.get(i))){
final String outputURL = rootOutURL + memberList.get(i).photoPath;
String photoURL = rootInURL + "photos/" + memberList.get(i).photoPath;
Picasso.with(this)
.load(photoURL)
.into(new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
File file = new File(outputURL);
try{
file.createNewFile();
FileOutputStream outputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG,100,outputStream);
outputStream.flush();
outputStream.close();
Toast.makeText(context, "YEpa: " ,Toast.LENGTH_LONG).show();
} catch (IOException e){
Toast.makeText(context, "Error: " + e.toString(),Toast.LENGTH_LONG).show();
}
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
}
}
}
Upvotes: 1
Views: 3102
Reputation: 317
Try this and your error should disappear. This problem always happens when you use it in Unit Android test
kotlin code
Handler(Looper.getMainLooper()).post {
}
java code
new Handler(Looper.getMainLooper()).post(() -> {
});
Upvotes: 3
Reputation: 2460
You can't update an ui element from a different thread than the one which created that ui element. On Android that almost always means the main thread.
What you need to do is send back the photoUrl
String to your activity or fragment on the main thread. The traditional way of doing it is by using a Handler
. You can read about this more here: https://developer.android.com/training/multiple-threads/communicate-ui.html
Upvotes: 2