2013-01-10 38 views
0

我的應用程序使用GridView從JSON獲取圖像。一切都很好,但現在我想通過點擊按鈕來加載更多。我按照這個教程Android ListView with Load More Button。 當我跟着它,我用runOnUiThread(new Runnable() { public void run() { } }doInBackground,但它的錯誤NetworkOnMainThreadException我知道這個因爲我在UI線程上運行它。但是當我刪除runOnUiThread...時,它也會出錯加載更多 - 只有創建視圖層次結構的原始線程才能觸及其視圖

我該如何解決這個錯誤?完整的源http://pastie.org/5659969

01-10 14:39:14.970: E/AndroidRuntime(19609): FATAL EXCEPTION: AsyncTask #3 
01-10 14:39:14.970: E/AndroidRuntime(19609): java.lang.RuntimeException: An error occured while executing doInBackground() 
01-10 14:39:14.970: E/AndroidRuntime(19609): at android.os.AsyncTask$3.done(AsyncTask.java:299) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at java.lang.Thread.run(Thread.java:856) 
01-10 14:39:14.970: E/AndroidRuntime(19609): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 
01-10 14:39:14.970: E/AndroidRuntime(19609): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4847) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:974) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at android.view.ViewGroup.invalidateChild(ViewGroup.java:4075) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at android.view.View.invalidate(View.java:10525) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at android.view.View.invalidate(View.java:10480) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at android.widget.ImageView.invalidateDrawable(ImageView.java:190) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at android.graphics.drawable.Drawable.invalidateSelf(Drawable.java:350) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at android.graphics.drawable.Drawable.setVisible(Drawable.java:546) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at android.widget.ImageView.onDetachedFromWindow(ImageView.java:1173) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at android.view.View.dispatchDetachedFromWindow(View.java:12096) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2541) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at android.view.ViewGroup.removeAllViewsInLayout(ViewGroup.java:3828) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at android.widget.AbsListView.resetList(AbsListView.java:2130) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at android.widget.GridView.setAdapter(GridView.java:170) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at com.camitss.mcolle.CardActivity$LoadMore.doInBackground(CardActivity.java:254) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at com.camitss.mcolle.CardActivity$LoadMore.doInBackground(CardActivity.java:1) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at android.os.AsyncTask$2.call(AsyncTask.java:287) 
01-10 14:39:14.970: E/AndroidRuntime(19609): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
01-10 14:39:14.970: E/AndroidRuntime(19609): ... 5 more 

的AsyncTask當第一負載使用按鈕時,點擊加載更多

// load more 

public class LoadMore extends AsyncTask<String, Void, Void> { 

    String token = getIntent().getExtras().getString("token1"); 

    protected void onPreExecute() { 
     super.onPreExecute(); 
     showDialog(DIALOG_DOWNLOAD_JSON_PROGRESS); 
    } 

    @Override 
    protected Void doInBackground(String... params) { 
       num_page += 1; 
       String url = "http://xxx.xxx.xxx/card/all/"+num_page+"/0/?token="+token; 
       JSONArray data = null; 

       try { 

        JSONObject jsonObject = new JSONObject(getJSONUrl(url)); 

        MyArrList = new ArrayList<HashMap<String, Object>>(); 
        HashMap<String, Object> map; 
        data = jsonObject.getJSONArray("data"); 
        for (int i = 0; i < data.length(); i++) { 
         JSONObject c = data.getJSONObject(i); 
         map = new HashMap<String, Object>(); 

         // Thumbnail Get ImageBitmap To Object 
         map.put("cardimage", (String) c.getString("cardimage")); 
         map.put("ImageThumBitmap",(Bitmap) loadBitmap(c.getString("cardimage"))); 
         map.put("categoryid", (String) c.getString("categoryid")); 
         MyArrList.add(map); 
        } 

        int currentPosition = gridView1.getFirstVisiblePosition(); 
        ImageAdapter adapter = new ImageAdapter(CardActivity.this, MyArrList); 
        gridView1.setAdapter(adapter); 
        gridView1.setSelection(currentPosition + 1); 

       } catch (JSONException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
     return null; 
    } 

    protected void onPostExecute(Void unused) { 
     ShowAllContent(); 
     dismissDialog(DIALOG_DOWNLOAD_JSON_PROGRESS); 
     removeDialog(DIALOG_DOWNLOAD_JSON_PROGRESS); 
    } 

} 

回答

2

你或許應該提出這個代碼

// Download JSON in Background 
public class DownloadJSONFileAsync extends AsyncTask<String, Void, Void> { 
    String token = getIntent().getExtras().getString("token1"); 

    protected void onPreExecute() { 
     super.onPreExecute(); 
     showDialog(DIALOG_DOWNLOAD_JSON_PROGRESS); 
    } 

    @Override 
    protected Void doInBackground(String... params) { 
     String url = "http://xxx.xxx.xxx/card/all/"+num_page+"/0/?token="+token; 
     JSONArray data = null; 

     try { 

      JSONObject jsonObject = new JSONObject(getJSONUrl(url)); 
      MyArrList = new ArrayList<HashMap<String, Object>>(); 
      HashMap<String, Object> map; 
      data = jsonObject.getJSONArray("data"); 

      for (int i = 0; i < data.length(); i++) { 
       JSONObject c = data.getJSONObject(i); 
       map = new HashMap<String, Object>(); 

       // Thumbnail Get ImageBitmap To Object 
       map.put("cardimage", (String) c.getString("cardimage")); 
       map.put("ImageThumBitmap",(Bitmap) loadBitmap(c.getString("cardimage"))); 
       map.put("categoryid", (String) c.getString("categoryid")); 
       MyArrList.add(map); 
      } 

     } catch (JSONException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    protected void onPostExecute(Void unused) { 
     ShowAllContent(); // When Finish Show Content 
     dismissDialog(DIALOG_DOWNLOAD_JSON_PROGRESS); 
     removeDialog(DIALOG_DOWNLOAD_JSON_PROGRESS); 
    } 

} 

AsycTask:

   int currentPosition = gridView1.getFirstVisiblePosition(); 
       ImageAdapter adapter = new ImageAdapter(CardActivity.this, MyArrList); 
       gridView1.setAdapter(adapter); 
       gridView1.setSelection(currentPosition + 1); 

進入onPostExecute方法,因爲它必須在UI線程上運行

+0

gridview1.setSelection(currentPosition + 1)中的'1'是什麼意思?'cuz我把它改爲0它工作得很好 – kongkea

+0

非常感謝你的回答。節省了我很多時間....謝謝,我需要在pnPostExecute()insted doInBackground上添加我的setadaper –

相關問題