2012-01-25 20 views
0

我想使用線程從Internet檢索圖像,並且一旦圖像完成下載,我就使用處理程序在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是在活動中的私有類,我用的初始化處理程序發佈與下載新的圖像更新imageview的onCreate方法:

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的ImageView的:

private void updateDisplayPhoto(Bitmap photo) { 
    imageView.setImageBitmap(photo); 
} 

這些所有以上都是一樣的活動的一部分。就像我說的,在帶有ICS的Nexus S上,它可以正常工作,但在具有Android 2.1更新的三星上,圖像永遠不會在UI中更新。我做錯了什麼?

回答

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(); 
     } 
    } 
+0

如何在我的活動添加此的AsyncTask ..任何教程這個.. –

+0

最好的是[這](http://developer.android.com/reference/android/os/AsyncTask.html)和例如 –

+0

和[這裏](http://stackoverflow.com/questions/8612406/android-os-networkonmainthreadexception-need-to-use-async-task/8612418#​​8612418)是一個例子,你可以如何做到這一點。 –

相關問題