2015-02-24 135 views
0

我試圖從AsyncTask類返回一個ArrayList返回到MainAcitivity類,然後使用這個ArrayList填充MainActivity中的gridview。ASyncTask並返回一個ArrayList

parseURL需要一個String參數來解析url。當用戶點擊按鈕時,parseURL被執行。我編譯並運行的代碼,但在觸發按鈕事件後未填充gridview並且按下按鈕兩次會使應用程序崩潰。

編輯︰加入循環回調後,它停止崩潰,但它仍然不會填充gridview。,我想填充GridView中ArrayList對象是這種格式10,John,Smith

這裏是我的MainActivity代碼(使用斯坦尼斯拉夫·博德納爾建議)

private GridView grid1; 
private ArrayAdapter<String> adapter; 

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    //initalized the grid and adapter 
    grid1 = (GridView)findViewById(R.id.gridView1); 

    adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1); 
    grid1.setAdapter(adapter); 
} 

public void onButtonClick(View v) { 
EditText textInput = (EditText) findViewById(R.id.editText1); 
String code = textInput.getText().toString(); 

new parseURL() { 
    @Override 
    protected void onPostExecute(List<String> list) { 
     //use the list from parseURL to fill grid view 
     ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list); 

     gridView.setAdapter(adapter); 
     adapter.notifyDataSetChanged(); 
    } 
}.execute(code); 

的parseURL類

public class parseURL extends AsyncTask<String, Void, List<String>> { 

protected List<String> doInBackground(String... params) { 
    List<String> str = new ArrayList<String>(); 
    try { 
     Document doc = Jsoup.connect("http://www.mywebsite.com/id/" + params).get(); 

     Elements row1 = doc.select("table"); 
     Elements row2 = doc.select("td"); 
     Elements row3 = doc.select("td"); 

     for (int i = 0; i < row1.size(); i++) { 
      str.add(row1.get(i).text() + "," + row2.get(i).text() + "," + row2.get(i).text()); 
     } 
     return str; 
    } catch (Exception e) { 
     return new ArrayList<String>(); 
    } 
} 
+0

我不知道爲什麼在GridView未填充,但的AsyncTask只能一次(如果第二試圖執行一個異常將被拋出。) – Prudhvi 2015-02-24 22:09:25

+0

,因爲你不執行爲'列表 str;'分配新的列表,'str.add'會立即拋出NullPointerException?並與空'catch'你從來沒有機會知道這一點...... – 2015-02-24 22:09:56

回答

1

您可以添加加載回調。

public void onButtonClick(View v) { 
    EditText textInput = (EditText) findViewById(R.id.editText1); 
    String code = textInput.getText().toString(); 

    new parseURL() { 
     @Override 
     protected void onPostExecute(List<String> list) { 
      //use the list from parseURL to fill grid view 
      ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list); 

      gridView.setAdapter(adapter); 
      adapter.notifyDataSetChanged(); 
     } 
    }.execute(code); 
} 

的AsyncTask:

public class parseURL extends AsyncTask<String, Void, List<String>> { 

    protected List<String> doInBackground(String... params) { 
     List<String> str = new ArrayList<String>(); 
     try { 
      Document doc = Jsoup.connect("http://www.mywebsite.com/id/" + params).get(); 

      Elements row1 = doc.select("table"); 
      Elements row2 = doc.select("td"); 
      Elements row3 = doc.select("td"); 

      for (int i = 0; i < row1.size(); i++) { 
       str.add(row1.get(i).text() + "," + row2.get(i).text() + "," + row2.get(i).text()); 
      } 
      return str; 
     } catch (Exception e) { 
      return new ArrayList<String>(); 
     } 
    } 
} 

補充

如果通過onPostExecute返回非空網格陣列名單將在接下來的方式來填充每個單元都會有串10,約翰·史密斯。請檢查該方法doInBackground不會捕獲一些異常並正確填充數組列表。

接下來如果你想做一個表視圖,其中1行將包含3列10 |約翰|然後Smith將數據解析爲對象結構:

class Person { 
    private int id; 
    private String firstName; 
    private String lastName; 
} 

然後改變方法doInBackground返回Person對象的數組列表。

在使用Person對象的init視圖中創建自定義適配器(擴展BaseAdapter)。 視圖將作爲水平方向的LinearLayout,它將包含3個帶有佈局權重的TextView(android:layout_weight =「0.3」 - 在每個TextView中設置,您可以更改此值)。然後使用ListView而不是GridView。列表視圖的每一行將包含1個人。

+0

我嘗試了這一點,它仍然不會填充GridView,但它會在第一次點擊按鈕後停止崩潰。解析後的字符串arraylist對象就像這個'10,John,Smith'。在將其放入適配器並將gridview設置爲適配器之前,需要更改格式嗎?我還在MainActivity onCreate()中初始化了我的gridview和適配器,並在layout.xml中將列數設置爲3 – user1281921 2015-02-24 23:00:52

1

的的AsyncTask按定義是異步的。你的代碼處理它就像它是同步的。

移動

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list); 

gridView.setAdapter(adapter); 
adapter.notifyDataSetChanged(); 

到SETLIST方法。

此外,傳遞MainActivity時感覺有點不穩定。如果在異步任務期間活動被破壞會發生什麼? 相反,使AsyncTask成爲MainActivity中的私有內部類或匿名類

當然,在填充它之前,您需要初始化列表。

+0

我試過這個,它仍然不會填充GridView,但它停止後第一個按鈕單擊:)崩潰。字符串arraylist對象就像這個'10,John,Smith'。在將其放入適配器並將gridview設置爲適配器之前,需要更改格式嗎?我還在MainActivity onCreate()中初始化了我的gridview和適配器。 – user1281921 2015-02-24 22:59:52

1

不要做gridview.setAdapter()兩次。該代碼存在一些問題。由於P-aBäckström寫道:

此外,繞過MainActivity傳遞感覺有點不穩定。如果在異步任務期間活動被破壞會發生什麼?相反,使AsyncTask成爲MainActivity中的私有內部類或匿名類

您需要修復該問題。現在來更新部件:

聲明全局處理程序是這樣的:

private final Handler handler = new Handler() { 
    @Override 
    public void handleMessage(Message msg) { 
     if(msg.what == 1) { 
      List<String> list = (List) msg.obj; 
      adapter.insert(list); 
      adapter.notifyDataSetChanged(); 
     } 
    } 
}; 

然後在onPostExecute()使用handler您的數據發送到UI線程和更新GridView控件:

protected void onPostExecute(List<String> list) { 
    handler.obtainMessage(1, list); 
} 
1

試這個:

主要活動類別

private GridView grid1; 
private ArrayAdapter<String> adapter; 

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    //initalized the grid and adapter 
    grid1 = (GridView)findViewById(R.id.gridView1); 

    adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1); 
    grid1.setAdapter(adapter); 
} 

public void onButtonClick(View v) { 
    EditText textInput = (EditText) findViewById(R.id.editText1); 
    String code = textInput.getText().toString(); 
    new parseURL(this).execute(code); 
} 

public void onBackgroundTaskCompleted(List<String> result) { 
    // TODO Auto-generated method stub 
    Log.i(TAG, "onBackgroundTaskCompleted List: "+result); 

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list); 

    gridView.setAdapter(adapter); 
    adapter.notifyDataSetChanged(); 
} 

的AsyncTask:

public class parseURL extends AsyncTask<String, Void, List<String>> { 

MainActivity caller; 

    public Scheduler(MainActivity mainActivity) { 
     // TODO Auto-generated constructor stub 
     this.caller = mainActivity; 
    } 
    protected void onPostExecute(List<String> result) { 
      caller.onBackgroundTaskCompleted(result); 
    } 

    protected List<String> doInBackground(String... params) { 
     List<String> str = new ArrayList<String>(); 
     try { 
      Document doc = Jsoup.connect("http://www.mywebsite.com/id/" + params).get(); 

      Elements row1 = doc.select("table"); 
      Elements row2 = doc.select("td"); 
      Elements row3 = doc.select("td"); 

      for (int i = 0; i < row1.size(); i++) { 
       str.add(row1.get(i).text() + "," + row2.get(i).text() + "," + row2.get(i).text()); 
      } 
      return str; 
     } catch (Exception e) { 
      return new ArrayList<String>(); 
     } 
    } 
}