我试图将一个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>();
}
}
答案 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>();
}
}
}