2015-02-24 92 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>(); 
     } 
    } 
}