我正在制作一个应用程序,获得一些XML并解析它,使对象的数组列表传递给另一个活动。这都是在AsyncTask中完成的。当我运行应用程序时,它立即崩溃,我很难找出问题出在哪里。非常感谢任何帮助。
Main Activity
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.ArrayList;
import org.xmlpull.v1.XmlPullParserException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.util.Log;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {
ProgressDialog progressDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new QuizWorker().execute("http://liisp.uncc.edu/~mshehab/api/trivia.xml");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
// START QuizWorker Class
public class QuizWorker extends AsyncTask<String, Void, ArrayList<Question>> {
@Override
protected ArrayList<Question> doInBackground(String... params) {
String urlString = params[0];
try {
URL url = new URL(urlString);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.connect();
int statusCode = con.getResponseCode();
if(statusCode == HttpURLConnection.HTTP_OK) {
InputStream in = con.getInputStream();
return QuestionUtil.parseQuestions(in);
}
}
catch (MalformedURLException e) {
e.printStackTrace();
}
catch (ProtocolException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
catch (XmlPullParserException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(ArrayList<Question> result) {
super.onPostExecute(result);
progressDialog.dismiss();
TextView tv = (TextView) findViewById(R.id.ready_status);
tv.setText("Trivia Ready");
// testing purposes
Log.d("demo", result.toString());
}
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setCancelable(false);
progressDialog.setMessage("Loading Trivia");
progressDialog.show();
}
} // END Class
} // END Activity
正如你所看到的,我有MainActivity
在这里与AsyncTask。AsyncTask调用另一个类QuestionUtil
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
public class QuestionUtil {
static ArrayList<Question> parseQuestions(InputStream xmlIn) throws XmlPullParserException, IOException {
XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
parser.setInput(xmlIn, "UTF-8");
Question question = null;
ArrayList<Question> questionList = new ArrayList<Question>();
Choices choices = null;
ArrayList<Choices> choiceList = new ArrayList<Choices>();
int event = parser.getEventType();
while (event != XmlPullParser.END_DOCUMENT) {
switch (event) {
case XmlPullParser.START_TAG:
if(parser.getName().equals("question")) {
question = new Question();
try {
question.setId(parser.getAttributeValue(null, "id"));
}
catch (NumberFormatException ex) { }
}
else if (parser.getName().equals("text")) {
question.setText(parser.nextText());
}
else if (parser.getName().equals("image")) {
question.setImage(parser.nextText());
}
else if (parser.getName().equals("choices")) {
boolean isCorrect;
String answer;
parser.next();
while (parser.getName().equals("choice")) {
if (parser.getAttributeValue(null, "answer") != null) {
isCorrect = true;
answer = parser.nextText();
choices = new Choices(isCorrect, answer);
}
else {
isCorrect = false;
answer = parser.nextText();
choices = new Choices(isCorrect, answer);
}
choiceList.add(choices);
parser.next();
}
question.setChoices(choiceList);
} // END Choices Parsing
break;
case XmlPullParser.END_TAG:
if (parser.getName().equals("question")) {
questionList.add(question);
question = null;
}
break;
default:
break;
} // END Switch
event = parser.next();
} // END While loop
return questionList;
}
}
这个类使用PULL解析出XML,并使我的Question
类的对象的数组列表:
import java.util.ArrayList;
import android.os.Parcel;
import android.os.Parcelable;
public class Question implements Parcelable {
public String id;
public String text;
public String image;
public ArrayList<Choices> choices;
public Question() {
// TODO Auto-generated constructor stub
}
// Constructs a Question from values
public Question (String id, String text, String image, ArrayList<Choices> choices) {
this.id = id;
this.text = text;
this.image = image;
this.choices = choices;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public ArrayList<Choices> getChoices() {
return choices;
}
public void setChoices(ArrayList<Choices> choices) {
this.choices = choices;
}
@Override
public String toString() {
return "Question [id=" + id + ", text=" + text + ", image=" + image
+ "]";
}
/**
* Constructs a Question from a Parcel
* @param parcel Source Parcel
*/
public Question (Parcel parcel) {
this.id = parcel.readString();
this.text = parcel.readString();
this.image = parcel.readString();
this.choices = parcel.readArrayList(null);
}
@Override
public int describeContents() {
return 0;
}
// Required method to write to Parcel
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(id);
dest.writeString(text);
dest.writeString(image);
dest.writeList(choices);
}
// Method to recreate a Question from a Parcel
public static Creator<Question> CREATOR = new Creator<Question>() {
@Override
public Question createFromParcel(Parcel source) {
return new Question(source);
}
@Override
public Question[] newArray(int size) {
return new Question[size];
}
};
}
我也有一个叫做Choices
的类,我把答案,然后我做一个数组列表,我添加到每个问题对象。
当我运行代码时,应用程序甚至没有启动,只是立即说它停止工作了。日志说它在doInBackground中。
Log/Errors
03-17 15:52:51.509: D/dalvikvm(2032): GC_FOR_ALLOC freed 93K, 5% free 3020K/3168K, paused 2ms, total 4ms
03-17 15:52:51.509: I/dalvikvm-heap(2032): Grow heap (frag case) to 3.607MB for 635808-byte allocation
03-17 15:52:51.529: D/dalvikvm(2032): GC_FOR_ALLOC freed 5K, 5% free 3635K/3792K, paused 13ms, total 13ms
03-17 15:52:51.589: D/(2032): HostConnection::get() New Host Connection established 0xb8e93af0, tid 2032
03-17 15:52:51.629: W/EGL_emulation(2032): eglSurfaceAttrib not implemented
03-17 15:52:51.629: D/OpenGLRenderer(2032): Enabling debug mode 0
03-17 15:52:51.679: W/EGL_emulation(2032): eglSurfaceAttrib not implemented
03-17 15:52:51.799: W/dalvikvm(2032): threadid=11: thread exiting with uncaught exception (group=0xb2cbdb20)
03-17 15:52:51.799: E/AndroidRuntime(2032): FATAL EXCEPTION: AsyncTask #1
03-17 15:52:51.799: E/AndroidRuntime(2032): Process: com.example.midterm, PID: 2032
03-17 15:52:51.799: E/AndroidRuntime(2032): java.lang.RuntimeException: An error occured while executing doInBackground()
03-17 15:52:51.799: E/AndroidRuntime(2032): at android.os.AsyncTask$3.done(AsyncTask.java:300)
03-17 15:52:51.799: E/AndroidRuntime(2032): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
03-17 15:52:51.799: E/AndroidRuntime(2032): at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
03-17 15:52:51.799: E/AndroidRuntime(2032): at java.util.concurrent.FutureTask.run(FutureTask.java:242)
03-17 15:52:51.799: E/AndroidRuntime(2032): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
03-17 15:52:51.799: E/AndroidRuntime(2032): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
03-17 15:52:51.799: E/AndroidRuntime(2032): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
03-17 15:52:51.799: E/AndroidRuntime(2032): at java.lang.Thread.run(Thread.java:841)
03-17 15:52:51.799: E/AndroidRuntime(2032): Caused by: java.lang.NullPointerException
03-17 15:52:51.799: E/AndroidRuntime(2032): at com.example.midterm.QuestionUtil.parseQuestions(QuestionUtil.java:54)
03-17 15:52:51.799: E/AndroidRuntime(2032): at com.example.midterm.MainActivity$QuizWorker.doInBackground(MainActivity.java:60)
03-17 15:52:51.799: E/AndroidRuntime(2032): at com.example.midterm.MainActivity$QuizWorker.doInBackground(MainActivity.java:1)
03-17 15:52:51.799: E/AndroidRuntime(2032): at android.os.AsyncTask$2.call(AsyncTask.java:288)
03-17 15:52:51.799: E/AndroidRuntime(2032): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
03-17 15:52:51.799: E/AndroidRuntime(2032): ... 4 more
03-17 15:52:52.169: E/WindowManager(2032): android.view.WindowLeaked: Activity com.example.midterm.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{b2faf408 V.E..... R......D 0,0-456,144} that was originally added here
03-17 15:52:52.169: E/WindowManager(2032): at android.view.ViewRootImpl.<init>(ViewRootImpl.java:348)
03-17 15:52:52.169: E/WindowManager(2032): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248)
03-17 15:52:52.169: E/WindowManager(2032): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
03-17 15:52:52.169: E/WindowManager(2032): at android.app.Dialog.show(Dialog.java:286)
03-17 15:52:52.169: E/WindowManager(2032): at com.example.midterm.MainActivity$QuizWorker.onPreExecute(MainActivity.java:101)
03-17 15:52:52.169: E/WindowManager(2032): at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:587)
03-17 15:52:52.169: E/WindowManager(2032): at android.os.AsyncTask.execute(AsyncTask.java:535)
03-17 15:52:52.169: E/WindowManager(2032): at com.example.midterm.MainActivity.onCreate(MainActivity.java:28)
03-17 15:52:52.169: E/WindowManager(2032): at android.app.Activity.performCreate(Activity.java:5231)
03-17 15:52:52.169: E/WindowManager(2032): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
03-17 15:52:52.169: E/WindowManager(2032): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
03-17 15:52:52.169: E/WindowManager(2032): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
03-17 15:52:52.169: E/WindowManager(2032): at android.app.ActivityThread.access$800(ActivityThread.java:135)
03-17 15:52:52.169: E/WindowManager(2032): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
03-17 15:52:52.169: E/WindowManager(2032): at android.os.Handler.dispatchMessage(Handler.java:102)
03-17 15:52:52.169: E/WindowManager(2032): at android.os.Looper.loop(Looper.java:136)
03-17 15:52:52.169: E/WindowManager(2032): at android.app.ActivityThread.main(ActivityThread.java:5017)
03-17 15:52:52.169: E/WindowManager(2032): at java.lang.reflect.Method.invokeNative(Native Method)
03-17 15:52:52.169: E/WindowManager(2032): at java.lang.reflect.Method.invoke(Method.java:515)
03-17 15:52:52.169: E/WindowManager(2032): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
03-17 15:52:52.169: E/WindowManager(2032): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
03-17 15:52:52.169: E/WindowManager(2032): at dalvik.system.NativeStart.main(Native Method)
任何帮助都将非常感激。我的代码中没有错误,我只是不知道什么可能是错误的,为什么它甚至没有开始。
关于日志的这一部分:
03-17 15:52:52.169: E/WindowManager(2032): android.view.WindowLeaked: Activity com.example.midterm.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{b2faf408 V.E..... R......D 0,0-456,144} that was originally added here
03-17 15:52:52.169: E/WindowManager(2032): at android.view.ViewRootImpl.<init>(ViewRootImpl.java:348)
03-17 15:52:52.169: E/WindowManager(2032): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248)
03-17 15:52:52.169: E/WindowManager(2032): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
03-17 15:52:52.169: E/WindowManager(2032): at android.app.Dialog.show(Dialog.java:286)
我建议你看看这个链接。我想只要另一个错误不再发生,这个就可以工作了。
下面一行表示存在一个NullPointerException。要确定什么是空,有必要知道QuestionUtil.java:54是哪一行。
03-17 15:52:51.799: E/AndroidRuntime(2032): at com.example.midterm.QuestionUtil.parseQuestions(QuestionUtil.java:54)