ASyncTask 并返回一个 ArrayList
ASyncTask and returning an ArrayList
我正在尝试 return 从 AsyncTask class 返回 MainAcitivity class 的 ArrayList,然后使用此 arraylist 填充 MainActivity 中的 gridview。
parseURL 采用字符串参数来解析 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);
解析网址 class
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>();
}
}
AsyncTask 根据定义是异步的。您的代码处理它就像它是同步的。
移动
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list);
gridView.setAdapter(adapter);
adapter.notifyDataSetChanged();
进入setList方法。
此外,绕过 MainActivity 感觉有点不稳定。如果 Activity 在异步任务期间被销毁会怎样?
相反,将 AsyncTask 设为私有内部 class 或 MainActivity
中的匿名 class
当然,您需要在填充列表之前对其进行初始化。
您可以添加加载回调。
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);
}
异步任务:
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>();
}
}
}
补充
如果 returns by onPostExecute 的数组列表不为空,您的网格将以接下来的方式填充,每个单元格将包含字符串 10,John,Smith。请检查 doInBackground 方法是否未捕获某些异常并正确填充数组列表。
接下来,如果您想创建一个 table 视图,其中 1 行将包含 3 列 10 |约翰 | Smith 然后将数据解析成对象结构:
class Person {
private int id;
private String firstName;
private String lastName;
}
然后将方法 doInBackground 更改为 return Person 对象的数组列表。
创建自定义适配器(扩展 BaseAdapter),其中初始化视图使用 Person 对象。
视图将作为水平方向的 LinearLayout,其中将包含 3 个具有布局权重的 TextView(android:layout_weight="0.3" - 在每个 TextView 中设置,您可以更改此值)。然后使用 ListView 而不是 GridView。列表视图的每一行将包含 1 个人。
不要 gridview.setAdapter()
两次。该代码存在一些问题。正如 P-a Bäckström 所写:
Also, passing around the MainActivity feels a bit shaky. What happens if the Activity is destroyed during the async-task? Instead, make the AsyncTask a private inner class or an anonymous class in 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);
}
试试这个:
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();
}
异步任务:
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>();
}
}
}
我正在尝试 return 从 AsyncTask class 返回 MainAcitivity class 的 ArrayList,然后使用此 arraylist 填充 MainActivity 中的 gridview。
parseURL 采用字符串参数来解析 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);
解析网址 class
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>();
}
}
AsyncTask 根据定义是异步的。您的代码处理它就像它是同步的。
移动
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list);
gridView.setAdapter(adapter);
adapter.notifyDataSetChanged();
进入setList方法。
此外,绕过 MainActivity 感觉有点不稳定。如果 Activity 在异步任务期间被销毁会怎样? 相反,将 AsyncTask 设为私有内部 class 或 MainActivity
中的匿名 class当然,您需要在填充列表之前对其进行初始化。
您可以添加加载回调。
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);
}
异步任务:
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>();
}
}
}
补充
如果 returns by onPostExecute 的数组列表不为空,您的网格将以接下来的方式填充,每个单元格将包含字符串 10,John,Smith。请检查 doInBackground 方法是否未捕获某些异常并正确填充数组列表。
接下来,如果您想创建一个 table 视图,其中 1 行将包含 3 列 10 |约翰 | Smith 然后将数据解析成对象结构:
class Person {
private int id;
private String firstName;
private String lastName;
}
然后将方法 doInBackground 更改为 return Person 对象的数组列表。
创建自定义适配器(扩展 BaseAdapter),其中初始化视图使用 Person 对象。 视图将作为水平方向的 LinearLayout,其中将包含 3 个具有布局权重的 TextView(android:layout_weight="0.3" - 在每个 TextView 中设置,您可以更改此值)。然后使用 ListView 而不是 GridView。列表视图的每一行将包含 1 个人。
不要 gridview.setAdapter()
两次。该代码存在一些问题。正如 P-a Bäckström 所写:
Also, passing around the MainActivity feels a bit shaky. What happens if the Activity is destroyed during the async-task? Instead, make the AsyncTask a private inner class or an anonymous class in 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);
}
试试这个:
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();
}
异步任务:
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>();
}
}
}