我正在尝试从托管的MySQL获取数据列表,然后在listview中返回结果。但是在使用碎片时我无法做到。
我收到以下错误:
com.example.test.myapp E / AndroidRuntime:FATAL EXCEPTION:AsyncTask#1 处理:com.exampletest.myapp,PID:31491 java.lang.RuntimeException:执行doInBackground()时发生错误 在android.os.AsyncTask $ 3.done(AsyncTask.java:300) 在java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) at java.util.concurrent.FutureTask.setException(FutureTask.java:222) 在java.util.concurrent.FutureTask.run(FutureTask.java:242) 在android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:231) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:587) 在java.lang.Thread.run(Thread.java:818) 引起:java.lang.ArrayIndexOutOfBoundsException:length = 1;索引= 1 在com.example.test.myapp.homeOperation.doInBackground(homeOperation.java:71) 在com.example.test.myapp.homeOperation.doInBackground(homeOperation.java:23) 在android.os.AsyncTask $ 2.call(AsyncTask.java:288) 在java.util.concurrent.FutureTask.run(FutureTask.java:237) 在android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:231) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:587) 在java.lang.Thread.run(Thread.java:818)
使用下面显示的类:我连接到服务器,然后我获取结果,所以我可以解析数据并放入ArrayLists。
public class homeOperation extends AsyncTask<String, Void, String> {
List<String> title_list = new ArrayList<String>();
List<String> id_list = new ArrayList<String>();
Context context;
AlertDialog alertDialog;
homeOperation(Context ctx) {
context = ctx;
}
@Override
protected String doInBackground(String... params) {
String type = params[0];
String login_url = "http://xxxx/data.php";
if (type.equals("home")) {
try {
String events = params[1];
String task_owner = params[2];
URL url = new URL(login_url);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
OutputStream outputStream = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
String post_data = URLEncoder.encode("events", "UTF-8") + "=" + URLEncoder.encode(events, "UTF-8") + "&"
+ URLEncoder.encode("task_owner", "UTF-8") + "=" + URLEncoder.encode(task_owner, "UTF-8");
bufferedWriter.write(post_data);
bufferedWriter.flush();
bufferedWriter.close();
outputStream.close();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
String result = "";
String line = "";
while ((line = bufferedReader.readLine()) != null) {
result += line;
}
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
String[] arr = result.split("--");
for (int i = 0; i < arr.length; i++) {
String cur = arr[i];
title_list.add(cur.split(":")[0]);
id_list.add(cur.split(":")[1]);
}
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onPreExecute() {
}
@Override
protected void onPostExecute(String result) {
Toast toast = Toast.makeText(this.context, result, Toast.LENGTH_LONG);
toast.show();
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
现在,这是我正在尝试从homeOperation类获取数据然后将数据放入ListView的类。
public class ContentFragment extends Fragment {
ListView lv;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.content_fragment, container, false);
lv = (ListView) view.findViewById(R.id.resultList);
String type = "home";
homeOperation homeOperation = new homeOperation(ContentFragment.this.getActivity());
homeOperation.execute(type, "", "");
// This is the array adapter, it takes the context of the activity as a
// first parameter, the type of list view as a second parameter and your
// array as a third parameter.
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(ContentFragment.this.getActivity(), android.R.layout.simple_list_item_1, homeOperation.title_list);
lv.setAdapter(arrayAdapter);
//addButton onClick
ImageButton addButton = (ImageButton) view.findViewById(R.id.addButton);
addButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
addPaige(view);
}
});
return view;
}
public void addPaige(View v) {
Intent goToAddPaige = new Intent(getActivity(), AddPaige.class);
startActivity(goToAddPaige);
}
}
我认为使用片段发送上下文时会出现问题。
答案 0 :(得分:1)
title_list
将没有数据,因为AsyncTask.execute()
将在lv.setAdapter(arrayAdapter);
之后完成。
因此,如果您想要使用足够的数据处理title_list
,请使用android.os.Handler
中的onPostExecute()
发送您的AsyncTask结果。
尝试如下:
您的AsyncTask
public class homeOperation extends AsyncTask<String,Void,String> {
List<String> title_list = new ArrayList<String>();
List<String> id_list = new ArrayList<String>();
Context context;
Handler handler;
AlertDialog alertDialog;
homeOperation(Context ctx, Handler hnd) {
context = ctx;
handler = hnd;
}
@Override
protected String doInBackground(String... params) {
String type = params[0];
String login_url = "http://xxxx/data.php";
if (type.equals("home")) {
try {
String events = params[1];
String task_owner = params[2];
URL url = new URL(login_url);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
OutputStream outputStream = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
String post_data = URLEncoder.encode("events", "UTF-8") + "=" + URLEncoder.encode(events, "UTF-8") + "&"
+ URLEncoder.encode("task_owner", "UTF-8") + "=" + URLEncoder.encode(task_owner, "UTF-8");
bufferedWriter.write(post_data);
bufferedWriter.flush();
bufferedWriter.close();
outputStream.close();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
String result = "";
String line = "";
while ((line = bufferedReader.readLine()) != null) {
result += line;
}
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
String[] arr = result.split("--");
for (int i = 0; i < arr.length; i++) {
String cur = arr[i];
title_list.add(cur.split(":")[0]);
id_list.add(cur.split(":")[1]);
}
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onPreExecute() {
}
@Override
protected void onPostExecute(String result) {
Toast toast = Toast.makeText(this.context, result, Toast.LENGTH_LONG);
toast.show();
handler.sendEmptyMessage(0);
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
您的片段
public class ContentFragment extends Fragment {
ListView lv;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.content_fragment,container,false);
lv = (ListView) view.findViewById(R.id.resultList);
ViewHandler viewHnd = new ViewHandler(ContentFragment.this); // add this handler for parameter of yout AsyncTask.
String type = "home";
homeOperation homeOperation = new homeOperation(ContentFragment.this.getActivity(), viewHnd);
homeOperation.execute(type, "", "");
// This is the array adapter, it takes the context of the activity as a
// first parameter, the type of list view as a second parameter and your
// array as a third parameter.
// ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(ContentFragment.this.getActivity() , android.R.layout.simple_list_item_1, homeOperation.title_list);
//
// lv.setAdapter(arrayAdapter);
//addButton onClick
ImageButton addButton = (ImageButton) view.findViewById(R.id.addButton);
addButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
addPaige(view);
}
});
return view;
}
public void addPaige(View v){
Intent goToAddPaige = new Intent(getActivity(), AddPaige.class);
startActivity(goToAddPaige);
}
private static class ViewHandler extends Handler {
private final WeakReference<ContentFragment> mFragment;
ViewHandler(ContentFragment fragment) {
mFragment = new WeakReference<ContentFragment>(fragment);
}
@Override
public void handleMessage(Message msg) {
ContentFragment fragment = mFragment.get();
if (fragment != null) {
fragment.handleMessage(msg);
}
}
}
private void handleMessage(Message msg) {
if (msg.what == 0) {
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(ContentFragment.this.getActivity() , android.R.layout.simple_list_item_1, homeOperation.title_list);
lv.setAdapter(arrayAdapter);
}
}
}
答案 1 :(得分:0)
替换:
for (int i = 0; i < arr.length; i++) {
String cur = arr[i];
title_list.add(cur.split(":")[0]);
id_list.add(cur.split(":")[1]);
}
使用:
for (int i = 0; i < arr.length; i++) {
String cur = arr[i];
String[] temp = cur.split(":");
if (temp.length == 2){
title_list.add(cur.split(":")[0]);
id_list.add(cur.split(":")[1]);
}
}
堆栈跟踪本身非常清晰:
java.lang.Thread.run(Thread.java:818) Caused by: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1 at
应转换为此行:
id_list.add(cur.split(":")[1]);
你不应该期望split method总会给你一定数量的子串。所以你必须写一个后备,当它没有。