ASyncTask并返回一个ArrayList

时间:2015-02-24 22:00:07

标签: java android android-asynctask

我试图将一个ArrayList从AsyncTask类返回到MainAcitivity类,然后使用这个arraylist填充MainActivity中的gridview。

parseURL使用String参数来解析url。并且当用户单击按钮时执行parseURL。我编译并运行的代码但触发按钮事件后没有填充gridview,按两次按钮会使应用程序崩溃。

编辑:添加循环回调后,它会停止崩溃,但它仍然不会填充gridview。我想填充gridview的ArrayList对象采用这种格式10,John,Smith

这是我的MainActivity代码(使用Stanislav Bodnar建议)

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>();
    }
}

4 个答案:

答案 0 :(得分: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中的私有内部类或匿名类

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

答案 1 :(得分: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,John,Smith。请检查方法doInBackground没有捕获一些异常并正确填充数组列表。

接下来,如果你想做一个表视图,其中1行将包含3列10 |约翰|史密斯然后将数据解析为对象结构:

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

然后更改方法doInBackground以返回Person对象的数组列表。

使用Person对象创建自定义适配器(扩展BaseAdapter),其中init视图。 视图将为具有水平方向的LinearLayout,其将包含3个具有布局权重的TextView(android:layout_weight =&#34; 0.3&#34; - 在每个TextView中设置,您可以更改此值)。然后使用ListView而不是GridView。列表视图的每一行都包含1个人。

答案 2 :(得分: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()中使用处理程序将数据发送到UI线程并更新gridview:

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

答案 3 :(得分:1)

试试这个:

Mainactivity.class

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>();
        }
    }
}