我正在尝试使用线程从Internet检索图像,并且我使用Handler在图像下载完成后在UI上显示图像。它在带有ICS的Nexus S上运行良好,但使用运行Android 2.1的三星,图像永远不会显示在屏幕上!
此外,奇怪的是,当我在线程内部使用断点进行逐步调试时,从INternet获取图像,代码运行正常并显示图像,但是当我放置断点时进一步向下,在线程外部,实际更新UI的代码是,图像不会显示,就像从未到达此代码一样。这是我的代码:
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();
...
使用工作线程启动图像检索的功能:
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();
}
RetrieveImageWorker是活动中的私有类,我使用onCreate方法初始化的处理程序来发布和更新下载新图像的imageview:
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()));
}
}
}
以下是用于接收位图以更新UI的NotifierImage线程:
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);
}
}
}
updateDisplayPhoto只更新UI的图像视图:
private void updateDisplayPhoto(Bitmap photo) {
imageView.setImageBitmap(photo);
}
以上所有这些都是同一活动的一部分。就像我说的,在带有ICS的Nexus S上,它工作正常,但在具有Android 2.1更新的三星上,图像永远不会在UI中更新。我做错了什么?
答案 0 :(得分:0)
只需使用AsyncTask
即可。将代码放入doInBackground()
中检索图像,并将图像设置为PostExecute()
中的ImageView。如果Android提供了一种漂亮而清晰的方式,为什么要使用Runnable和Thread。
private class MyAsyncTask extends AsyncTask<Void, Void, Void>
{
@Override
protected void onPreExecute() {
mProgressDialog = ProgressDialog.show(ActivityName.this, "Loading...", "Data is Loading...");
}
@Override
protected Void doInBackground(Void... params) {
// your network operation
return null;
}
ProgressDialog mProgressDialog;
@Override
protected void onPostExecute(Void result) {
mProgressDialog.dismiss();
}
}