I am trying to retrieve an image from the Internet using a thread, and I am using a Handler to display the image on the UI once the image has finished downloading. It works fine on the Nexus S with ICS, but using a Samsung running Android 2.1, the image never gets displayed on the screen!
Moreover, what is weird is that when I do step-by-step debugging with a breakpoint inside the thread where the image gets fetched from the INternet, the code runs fine and the image gets displayed, but when I put the breakpoint further down, outside the thread, where the code to actually update the UI is, the image does not get displayed, as if this code is never reached. Here is my code:
private Handler handler;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
formatter.setMinimumFractionDigits(2);
formatter.setMaximumFractionDigits(2);
handler = new Handler();
...
The function that starts the image retrieval by using a worker thread:
private void retrieveImage() {
DeviceInfo dv = new DeviceInfo(this);
String uri = MerchantProAPI.GET_CLIENT_IMAGE_URL;
uri += "?api_id=" + MerchantProAPI.API_ID;
uri += "&merchantphone=" + dv.getPhoneNumber();
uri += "&imei=" + dv.getDeviceId();
uri += "&customerid=" + customerno;
Thread thr = new Thread(null, new RetrieveImageWorker(uri), "RetrieveImage");
thr.start();
}
The RetrieveImageWorker is a private class in the activity, and I use the handler initialized in the onCreate method to post and update an imageview with the new image downloaded:
private class RetrieveImageWorker implements Runnable {
String uri;
Bitmap bm;
public RetrieveImageWorker(String uri) {
this.uri = uri;
}
@Override
public void run() {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(uri);
try {
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
String contentType = entity.getContentType().getValue();
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int halfScreen = metrics.widthPixels / 2;
int photoWidth = halfScreen > 200 ? 200 : halfScreen;
if (contentType.contains("image/jpeg") || contentType.contains("image/png") || contentType.contains("image/gif")) {
bm = BitmapFactory.decodeStream(entity.getContent());
if (bm.getWidth() > photoWidth)
bm = Bitmap.createScaledBitmap(bm, photoWidth, Math.round((photoWidth*bm.getHeight())/bm.getWidth()), false);
}
handler.post(new NotifierImage(bm));
} catch (Exception e) {
handler.post(new Notifier(e.getMessage()));
}
}
}
Here is the NotifierImage thread used to receive the bitmap in order to update the UI:
private class NotifierImage implements Runnable {
private Bitmap bm;
public NotifierImage(Bitmap bm) {
this.bm = bm;
}
@Override
public void run() {
if (this.bm != null) {
updateDisplayPhoto(bm);
}
}
}
The updateDisplayPhoto just updates an imageview of the UI:
private void updateDisplayPhoto(Bitmap photo) {
imageView.setImageBitmap(photo);
}
All of these above are part of the same Activity. Like I said, on the Nexus S with ICS, it works fine, but on a Samsung with Android 2.1-update, the image never gets updated in the UI. What did I do wrong?