Handler在后台从网络中检索图像的问题

时间:2012-01-25 05:16:15

标签: android multithreading handler

我正在尝试使用线程从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中更新。我做错了什么?

1 个答案:

答案 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();
        }
    }