2012-07-03 63 views
1

不知何故,我似乎並沒有得到它。 8-} 我有一個活動,我從數據庫請求JSON數據,返回結果包含一個圖片URL。我的應用在Android v2.x上運行良好,但由於偶然發現,在Android 4上出現了奇怪的行爲 - 包括未加載的圖像(這不是我稱之爲兼容性?!)現在我必須修復這個問題,希望修復不會再次破壞Android 2.x系統的功能!NetworkOnMainThreadException加載圖片如何

基本上,活動作品在網絡上的所有無數的例子說明(我刪除了最錯誤檢查等,以修剪下來的代碼主要部分):

new GetProductDetails().execute(); 
(..) 


class GetProductDetails extends AsyncTask<String, String, String> { 

    @Override 
    protected void onPreExecute() { 
      (..) 
    } 

    protected String doInBackground(String... args) { 

     // Building Parameters 
     List<NameValuePair> params = new ArrayList<NameValuePair>(); 
     params.add(new BasicNameValuePair("pid", pid)); 
     // getting product details by making HTTP request 
     JSONObject json = jsonParser.makeHttpRequest(
       getString(R.string.urlProductDetails), "GET", 
       params); 
     try { 
       JSONArray prodObj = json.getJSONArray(Consts.PRODS); 
       pinfo = prodObj.getJSONObject(0); 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 


    protected void onPostExecute(String file_url) { 
     // updating UI from Background Thread 
     runOnUiThread(new Runnable() { 
      public void run() { 
       // Storing each json item in variable 
       try { 

        String s = ""; 
        txtvname = (TextView) findViewById(R.id.txtpname); 
        txtshortinfo = (TextView) findViewById(R.id.txtshortinfo); 
(… populating activity window with json data …) 

      } 
     }); 


     // update image: 
     String imgURL; 
     try { 
      imgURL = pinfo.getString("pic_url"); 
      if (imgURL.length() > 1) { 
       imgURL = getString(R.string.urlPicsFull) + imgURL; 
       ImageView imgProd = (ImageView) findViewById(R.id.imgProduct); 
       Drawable drawable = LoadImageFromWebOperations(imgURL); 
       imgProd.setImageDrawable(drawable); 
      } 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
     pDialog.dismiss(); 
    } 

    private Drawable LoadImageFromWebOperations(String url) { 
     try { 
      InputStream is = (InputStream) new URL(url).getContent(); 
      Drawable d = Drawable.createFromStream(is, "src name"); 
      return d; 
     } catch (Exception e) { 
      System.out.println("Could not load " + url + ", Exc=" + e); 
      return null; 
     } 
    } 

現在,有一個加載圖像時出現android.os.NetworkOnMainThreadException。

回答

0

我想你的targetSDK版本太高了。 Here是關於哪些targetSDKVersion禁用了哪些兼容性行爲的一些文檔。 NetworkOnMainThreadException實際上從該列表中缺失。它被記錄爲here,如下所示:「這僅僅針對面向Honeycomb SDK或更高版本的應用程序而引發,針對早期SDK版本的應用程序允許在其主要事件循環線程上進行聯網,但非常不鼓勵。

因此,如果您將targetSDKVersion降至Honeycomb以下的值,則可以在主線程上進行聯網。將targetSDKVersion設置爲某個值就像是在說:「我在那個級別上測試了我的應用程序。」

  1. onPostExceute總是在主線程上運行。不需要在那裏使用runOnUiThread()。
  2. LoadImageFromWebOperations()需要在doInBackground()中調用,以便不在主線程上運行。這是造成異常的原因。
  3. onPostExecute獲取doInBackground返回的參數。因此,如果您不使用onPostExcecute中的參數並在doInBackground中始終返回null,則可以使用Void作爲結果類型(而不是字符串)