2014-02-15 52 views
0

我有包含的AsyncTask片段:的AsyncTask錯誤

class GetPharmacieDetails extends AsyncTask<String, String, String> { 
     /** 
     * Before starting background thread Show Progress Dialog 
     * */ 
     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      pDialog = new ProgressDialog(getActivity()); 
      pDialog.setMessage("Chargement. Patienter ..."); 
      pDialog.setIndeterminate(false); 
      pDialog.setCancelable(true); 
      pDialog.show(); 
     } 
     /** 
     * Getting product details in background thread 
     * */ 
     @Override 
     protected String doInBackground(String... args) { 
      // TODO Auto-generated method stub 
      int success; 
      try { 
       // Building Parameters 
       List<NameValuePair> params = new ArrayList<NameValuePair>(); 
       params.add(new BasicNameValuePair("latitude", pid)); 
       // getting product details by making HTTP request 
       // Note that product details url will use GET request 
       JSONObject json = jsonParser.makeHttpRequest(
         url_product_detials, "GET", params); 

       // check your log for json response 
       Log.d("Single Product Details", json.toString()); 

       // json success tag 
       success = json.getInt(TAG_SUCCESS); 
       if (success == 1) { 
        // successfully received product details 
        JSONArray productObj = json 
          .getJSONArray(TAG_PRODUCT); // JSON Array 

        // get first product object from JSON Array 
        JSONObject product = productObj.getJSONObject(0); 



        txtName.setText(product.getString(TAG_NAME)); 
        txtRegion.setText(product.getString(TAG_REGION)); 

        txtAddress.setText(product.getString(TAG_ADDRESS)); 
        lati = product.getString(TAG_LATITUDE); 
        longi = product.getString(TAG_LANGITUDE); 
       }else{ 
        // product with pid not found 
       } 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 
     return null; 

     } 

     /** 
     * After completing background task Dismiss the progress dialog 
     * **/ 
     protected void onPostExecute(String file_url) { 
      // dismiss the dialog once got all details 
      if(pDialog != null){ 
       pDialog.dismiss(); 
      } 

     } 
    } 

當我打開首次片段其運行良好,但是當我瀏覽到另一個片段,我返回另一個時間到它的第一個片段墜毀 登錄貓:

02-16 00:30:42.038: E/AndroidRuntime(2391): FATAL EXCEPTION: AsyncTask #5 
02-16 00:30:42.038: E/AndroidRuntime(2391): java.lang.RuntimeException: An error occured while executing doInBackground() 
02-16 00:30:42.038: E/AndroidRuntime(2391):  at android.os.AsyncTask$3.done(AsyncTask.java:299) 
02-16 00:30:42.038: E/AndroidRuntime(2391):  at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352) 
02-16 00:30:42.038: E/AndroidRuntime(2391):  at java.util.concurrent.FutureTask.setException(FutureTask.java:219) 
02-16 00:30:42.038: E/AndroidRuntime(2391):  at java.util.concurrent.FutureTask.run(FutureTask.java:239) 
02-16 00:30:42.038: E/AndroidRuntime(2391):  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 
02-16 00:30:42.038: E/AndroidRuntime(2391):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080) 
02-16 00:30:42.038: E/AndroidRuntime(2391):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573) 
02-16 00:30:42.038: E/AndroidRuntime(2391):  at java.lang.Thread.run(Thread.java:856) 
02-16 00:30:42.038: E/AndroidRuntime(2391): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 
02-16 00:30:42.038: E/AndroidRuntime(2391):  at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4746) 
02-16 00:30:42.038: E/AndroidRuntime(2391):  at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:854) 
02-16 00:30:42.038: E/AndroidRuntime(2391):  at android.view.ViewGroup.invalidateChild(ViewGroup.java:4075) 
02-16 00:30:42.038: E/AndroidRuntime(2391):  at android.view.View.invalidate(View.java:10386) 
02-16 00:30:42.038: E/AndroidRuntime(2391):  at android.view.View.invalidate(View.java:10341) 
02-16 00:30:42.038: E/AndroidRuntime(2391):  at android.widget.TextView.checkForRelayout(TextView.java:6439) 
02-16 00:30:42.038: E/AndroidRuntime(2391):  at android.widget.TextView.setText(TextView.java:3696) 
02-16 00:30:42.038: E/AndroidRuntime(2391):  at android.widget.TextView.setText(TextView.java:3554) 
02-16 00:30:42.038: E/AndroidRuntime(2391):  at android.widget.TextView.setText(TextView.java:3529) 
02-16 00:30:42.038: E/AndroidRuntime(2391):  at com.example.fitness2.InformationsSwipe$GetPharmacieDetails.doInBackground(InformationsSwipe.java:145) 
02-16 00:30:42.038: E/AndroidRuntime(2391):  at com.example.fitness2.InformationsSwipe$GetPharmacieDetails.doInBackground(InformationsSwipe.java:1) 
02-16 00:30:42.038: E/AndroidRuntime(2391):  at android.os.AsyncTask$2.call(AsyncTask.java:287) 
02-16 00:30:42.038: E/AndroidRuntime(2391):  at java.util.concurrent.FutureTask.run(FutureTask.java:234) 
02-16 00:30:42.038: E/AndroidRuntime(2391):  ... 4 more 
02-16 00:30:42.070: W/EGL_emulation(2391): eglSurfaceAttrib not implemented 
02-16 00:30:42.158: E/GooglePlayServicesUtil(2391): The Google Play services resources were not found. Check your project configuration to ensure that the resources are included. 

我認爲這個問題在這裏:

txtName.setText(product.getString(TAG_NAME)); 
txtRegion.setText(product.getString(TAG_REGION)); 
txtAddress.setText(product.getString(TAG_ADDRESS)); 
lati = product.getString(TAG_LATITUDE); 
longi = product.getString(TAG_LANGITUDE); 

回答

0

你可以「T更新從另一個線程UI線程(主線程),它會導致很多錯誤的內部,嘗試使product變量作爲地方,後來在onPostExecute設置文本到TextViews

class GetPharmacieDetails extends AsyncTask<String, String, String> { 
    /** 
    * Before starting background thread Show Progress Dialog 
    * */ 
    private JSONObject product; 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     pDialog = new ProgressDialog(getActivity()); 
     pDialog.setMessage("Chargement. Patienter ..."); 
     pDialog.setIndeterminate(false); 
     pDialog.setCancelable(true); 
     pDialog.show(); 
    } 
    /** 
    * Getting product details in background thread 
    * */ 
    @Override 
    protected String doInBackground(String... args) { 
     // TODO Auto-generated method stub 
     int success; 
     try { 
      // Building Parameters 
      List<NameValuePair> params = new ArrayList<NameValuePair>(); 
      params.add(new BasicNameValuePair("latitude", pid)); 
      // getting product details by making HTTP request 
      // Note that product details url will use GET request 
      JSONObject json = jsonParser.makeHttpRequest(
        url_product_detials, "GET", params); 

      // check your log for json response 
      Log.d("Single Product Details", json.toString()); 

      // json success tag 
      success = json.getInt(TAG_SUCCESS); 
      if (success == 1) { 
       // successfully received product details 
       JSONArray productObj = json 
         .getJSONArray(TAG_PRODUCT); // JSON Array 

       // get first product object from JSON Array 
       product = productObj.getJSONObject(0); 
      }else{ 
       // product with pid not found 
      } 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
    return null; 

    } 

    /** 
    * After completing background task Dismiss the progress dialog 
    * **/ 
    protected void onPostExecute(String file_url) { 
     // dismiss the dialog once got all details 
     if(null!=product){ 
      txtName.setText(product.getString(TAG_NAME)); 
       txtRegion.setText(product.getString(TAG_REGION)); 
       txtAddress.setText(product.getString(TAG_ADDRESS)); 
       lati = product.getString(TAG_LATITUDE); 
       longi = product.getString(TAG_LANGITUDE); 
     } 
     if(pDialog != null){ 
      pDialog.dismiss(); 
     } 

    } 
} 
+0

現在工作正常,謝謝;) – user3049804

+0

歡迎您:-) –

0

您正在更新doInBackground()中的UI。該方法在與GUI線程不同步的後臺線程上運行,因此產生CalledFromWrongThreadException結果。

一種選擇是使用runOnUiThread()方法在GUI線程上安排UI更新。請注意,這種方法屬於活動,所以你需要通過參考用它來片段的父:

getActivity().runOnUiThread(new Runnable() { 
    @Override 
    public void run() { 
     txtName.setText(product.getString(TAG_NAME)); 
     txtRegion.setText(product.getString(TAG_REGION)); 
     txtAddress.setText(product.getString(TAG_ADDRESS)); 
    } 
}); 

然而,使用正確的方法的AsyncTask是在onPostExecute(),執行任何用戶界面更新其與GUI線程同步。要做到這一點這樣,在的AsyncTask定義的JSONObject改變第三個參數(這就是你會從doInBackground返回類型,然後傳遞到onPostExecute):返回一個JSONObject

class GetPharmacieDetails extends AsyncTask<String, String, JSONObject> 

更改doInBackground:

protected JSONObject doInBackground(String... args) { 

...並不再更新doInBackground中的UI。相反,返回參照「產品」:

... 
if (success == 1) { 
    JSONArray productObj = json.getJSONArray(TAG_PRODUCT); 
    JSONObject product = productObj.getJSONObject(0); 

    //txtName.setText(product.getString(TAG_NAME)); 
    //txtRegion.setText(product.getString(TAG_REGION)); 
    //txtAddress.setText(product.getString(TAG_ADDRESS)); 

    lati = product.getString(TAG_LATITUDE); 
    longi = product.getString(TAG_LANGITUDE); 
    return product; 
}else{ 
... 

變化onPostExecute接收的JSONObject這裏更新UI,只要從doInBackground提供的參考不爲空:

protected void onPostExecute(JSONObject product) { 
    if (product != null) { 
     txtName.setText(product.getString(TAG_NAME)); 
     txtRegion.setText(product.getString(TAG_REGION)); 
     txtAddress.setText(product.getString(TAG_ADDRESS)); 
    } 

    // dismiss the dialog once got all details 
    if(pDialog != null){ 
     pDialog.dismiss(); 
    } 
}