简体   繁体   English

Android AsyncTask Xml拉解析

[英]Android AsyncTask Xml Pull Parsing

I am making an app that gets some XML and parses it, making an ArrayList of objects to be passed to another activity. 我正在制作一个获取一些XML并进行解析的应用程序,并制作了要传递给另一个活动的对象的ArrayList。 This is all done in an AsyncTask. 这些都是在AsyncTask中完成的。 When I run the app, it crashes immediately, and I'm having trouble figuring out where the problem lies. 当我运行该应用程序时,它立即崩溃,并且我无法确定问题出在哪里。 Any help is greatly appreciated. 任何帮助是极大的赞赏。

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

As you can see, I have the MainActivity here with the AsyncTask. 如您所见,我在这里具有AsyncTask的MainActivity The AsyncTask calls another class called QuestionUtil 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;

}

}

This class parses out the XML using PULL and makes an ArrayList of objects of my Question class: 此类使用PULL解析XML,并生成我Question类的对象的ArrayList:

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];
    }

};


}

I also have a class called Choices where I put the answers, then I make an ArrayList that I add to each Question object. 我还有一个名为Choices的类,在其中放置答案,然后创建一个ArrayList,将其添加到每个Question对象中。

When I run the code, the app doesn't even start, just immediately says that it stopped working. 当我运行代码时,该应用程序甚至无法启动,只是立即说它停止工作。 I think the log says it's in the doInBackground. 我认为日志说它在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)

Any help would be greatly appreciated. 任何帮助将不胜感激。 I have no errors in my code and I just can't figure out what might be wrong, why it's not even starting. 我的代码中没有错误,我只是想不出什么地方出了问题,为什么它甚至没有开始。

Concerning this part of your logcat: 关于logcat的这一部分:

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)

I recommend you to have a look at this link . 我建议您看一下此链接 I think this one will work as soon as the other error doesn't occur anymore. 我认为,只要不再发生其他错误,此功能就可以使用。

The following line says there is a NullPointerException. 下一行说有一个NullPointerException。 To determine what exactly is null, it's necessary to know which line QuestionUtil.java:54 is. 要确定确切为空的内容,有必要知道QuestionUtil.java:54在哪一行。

03-17 15:52:51.799: E/AndroidRuntime(2032):     at com.example.midterm.QuestionUtil.parseQuestions(QuestionUtil.java:54)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM