2013-08-22 71 views
0

我試圖從MySQL數據庫中獲取產品的詳細信息,但是當我編譯代碼時,即使我使用類GetProductDetails作爲AsyncTask執行時,也會收到NetworkOnMainThreadException錯誤。我不明白爲什麼會發生這種情況,因爲我正在按照教程做這件事,而且我沒有看到任何錯誤。這爲什麼會產生NetworkOnMainThreadException?

這是我使用的代碼:

public class ListClubs extends Activity { 

protected void onCreate(Bundle savedInstanceState) { 

super.onCreate(savedInstanceState); 
setContentView(R.layout.activity_clubs); 
new GetProductDetails().execute(); 

(...some code...)  
} 

class GetProductDetails extends AsyncTask<String, String, String> { 
     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      pDialog = new ProgressDialog(ListClubs.this); 
      pDialog.setMessage("Loading product details. Please wait..."); 
      pDialog.setIndeterminate(false); 
      pDialog.setCancelable(true); 
      pDialog.show(); 
     } 
    /** 
    * Getting product details in background thread 
    * */ 
    protected String doInBackground(String... params) { 

     // updating UI from Background Thread 
     runOnUiThread(new Runnable() { 
      public void run() { 
       // Check for success tag 
       int success; 
       try { 
        // Building Parameters 
        List<NameValuePair> params = new ArrayList<NameValuePair>(); 
        params.add(new BasicNameValuePair("pid", Integer.toString(1))); 

        // 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); 

        }else{ 
         // product with pid not found 
        } 
       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 

     return null; 
    } 

    protected void onPostExecute(String file_url) { 
     // dismiss the dialog once got all details 
     pDialog.dismiss(); 
    } 

} 

這是日誌:

FATAL EXCEPTION: main 
android.os.NetworkOnMainThreadException 
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117) 
at java.net.InetAddress.lookupHostByName(InetAddress.java:385) 
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236) 
at java.net.InetAddress.getAllByName(InetAddress.java:214) 
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137) 
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) 
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) 
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360) 
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) 
at com.goout.JSONParser.makeHttpRequest(JSONParser.java:62) 
at com.goout.ListClubs$GetProductDetails$1.run(ListClubs.java:464) 
at android.os.Handler.handleCallback(Handler.java:725) 
at android.os.Handler.dispatchMessage(Handler.java:92) 
at android.os.Looper.loop(Looper.java:137) 
at android.app.ActivityThread.main(ActivityThread.java:5227) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:511) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562) 
at dalvik.system.NativeStart.main(Native Method) 

謝謝!

+4

這是因爲'doInBackground()'中的整個代碼被封裝在發佈到UI線程的'Runnable'中,導致整個AsyncTask毫無意義。 –

回答

1

拿這個東西出來的doInbackground(),看看會發生什麼

runOnUiThread(new Runnable() { 
     public void run() { 

AsyncTask的一點是運行網絡的東西或doInBackground()任何繁重然後用其他的方法,如果需要更新UI。所以你不想做與其背景代碼(doInbackground())運行UI ThreadrunOnUiThread()相反的目的。

此外,really good information on AsyncTask Here

+0

真的!我也必須刪除公共無效運行(){}但在此之後它的工作 –

+0

是的,那部分是在我的答案。請點擊複選標記以在7分鐘內接受。此外,請務必閱讀我鏈接到的文檔,可能會多次,因爲它們起初很難理解,但非常有用。 – codeMagic

+0

哦,是的。對不起,我錯過了。但是,儘管如此,它會被接受爲答案。非常感謝! –

0

您再次從的AsyncTask一次編組所有的代碼到主界面,這是正確的,現在爲什麼它彷彿的AsyncTask不存在,一切都從UI線程跑。

提取您的網絡代碼以便在doInBackground方法中運行,並從中返回一個有意義的(到您的應用程序)類型,然後用代碼更新onPostExecute方法,並使用doInBackground的結果更新UI。 onPostExceute始終從Ui線程運行,如果您正確使用線程,則無需自行管理線程。

更多信息:http://developer.android.com/reference/android/os/AsyncTask.html

0

doInBackground方法添加runOnUiThread導致您的後臺線程來排隊一個可運行到你的主線程,所以一切的是可運行的內部(包括您的網絡任務)正在上運行主線程。在Android(Honeycomb +)中,這會導致拋出異常。

如果您發現在AsyncTask和特定網絡請求中遇到問題,請考慮查看庫以幫助簡化操作 - 例如droidQueryAndroid Volley

相關問題