解析XML fron URL并陷入循环

时间:2016-02-27 18:52:44

标签: android xml parsing url android-asynctask

我尝试从网址解析 XML 而没有获取任何数据,当我调试时,我发现我被卡在了{{ 1}}循环。在我放弃之前,变量我达到了160。我不知道为什么我陷入了while循环而没有进入循环中的任何if语句。

while()

修改:

这是新的public class Task extends AsyncTask<Void,Void,Void> { private List<Task> tasks; public Task() { } @Override protected Void doInBackground(Void... params) { makeTask(); return null; } public Task(String title){ mTitle = title; } private List<Task> makeTask(){ int i = 0; tasks = new ArrayList<>(); try { XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); factory.setNamespaceAware(true); XmlPullParser xpp = factory.newPullParser(); URL url = new URL("http://xxx"); InputStream stream = url.openStream(); xpp.setInput(stream, null); int eventType = xpp.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { if (eventType == XmlPullParser.START_DOCUMENT) { } else if (eventType == XmlPullParser.END_DOCUMENT) { } else if (eventType == XmlPullParser.START_TAG) { if (xpp.getName().equalsIgnoreCase("Task")) { tasks.add(new Task(xpp.nextText())); Log.d("Task: ", xpp.nextText()); } else if (eventType == XmlPullParser.END_TAG) { } else if (eventType == XmlPullParser.TEXT) { } eventType = xpp.next(); } i++; } } catch (MalformedURLException e) { e.printStackTrace(); } catch (XmlPullParserException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return tasks; } 循环,感谢@imsiso

while()

代码while (eventType != XmlPullParser.END_DOCUMENT) { if (eventType == XmlPullParser.START_TAG) { if (xpp.getName().equalsIgnoreCase("name")) { tasks.add(new Task(xpp.nextText())); } eventType = xpp.next(); } else eventType = xpp.next(); 中的以下行显示错误:

  

java.lang.NullPointerException:尝试调用接口方法&#39; int java.util.List.size()&#39;在空对象引用上

我认为我收到了这个错误,因为我没有等List<Task> tasks = task.getTasks();完成,也不知道我应该怎么做。

AsyncTask

3 个答案:

答案 0 :(得分:1)

这是一个示例TaskLoader和Loader for Callader。

private LoaderManager.LoaderCallbacks<List<TaskModel>> mLoaderCallbacks = new LoaderManager.LoaderCallbacks<List<TaskModel>>()
{
    @Override
    public Loader<List<TaskModel>> onCreateLoader(int id, Bundle args)
    {
        return new TaskLoader(getContext());
    }

    @Override
    public void onLoadFinished(Loader<List<TaskModel>> loader, List<TaskModel> data)
    {
        mTaskRV.setAdapter(new TaskAdapter(data));
    }

    @Override
    public void onLoaderReset(Loader<List<TaskModel>> loader)
    {
        //
    }
};

和TaskLoader。

private static class TaskLoader extends AsyncTaskLoader<List<TaskModel>>
{
    private static final String TAG = TaskLoader.class.getSimpleName();

    private List<TaskModel> mData = null;


    public TaskLoader(Context context)
    {
        super(context);
    }

    @Override
    protected void onStartLoading()
    {
        super.onStartLoading();
        if(mData != null){
            deliverResult(mData);
        }
        if(takeContentChanged() || mData == null){
            forceLoad();
        }
    }

    @Override
    public void deliverResult(List<TaskModel> data)
    {
        mData = data;
        super.deliverResult(data);
    }

    @Override
    public List<TaskModel> loadInBackground()
    {
        try{
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            factory.setNamespaceAware(true);
            XmlPullParser xpp = factory.newPullParser();
            URL url = new URL("http://xxx");
            InputStream in = null;
            try{
                in = url.openStream();
                xpp.setInput(in, "UTF-8");
                return parseTasks(xpp);
            }
            finally{
                if(in != null){
                    in.close();
                }
            }
        }
        catch(MalformedURLException e){
            Log.e(TAG, "loadInBackground", e);
        }
        catch(XmlPullParserException e){
            Log.e(TAG, "loadInBackground", e);
        }
        catch(IOException e){
            Log.e(TAG, "loadInBackground", e);
        }
        return null;
    }

    private List<TaskModel> parseTasks(XmlPullParser xpp)
        throws XmlPullParserException, IOException
    {
        ArrayList<TaskModel> tasks = new ArrayList<>();
        int eventType = xpp.getEventType();
        while(eventType != XmlPullParser.END_DOCUMENT){
            if(eventType == XmlPullParser.START_TAG){
                if(xpp.getName().equalsIgnoreCase("description")){
                    tasks.add(new TaskModel(xpp.nextText()));
                }
            }
            eventType = xpp.next();
        }
        return tasks;
    }
}

答案 1 :(得分:0)

您应该为doInBackground()完成时将触发的异步任务提供一个侦听器。例如:

public interface TaskListener{
   public void onTaskDone(List<Task> results);
}

public class Task extends AsyncTask<Void,Void,Void> {
  private List<Task> tasks;
  private TaskListener mListener;

  public Task(TaskListener listener)
  {
     this.mListener = listener;
  }
  protected Void doInBackground(Void... params) {
    .... xml parsing...
    if (mListener != null){
      mListener.onTaskDone(tasks);
    }
  }
}

并在您创建任务时:

Task task = new Task(this);

让该类实现TaskListener接口。

在此方法中,您将任务的结果提供给适配器。

public void onTaskDone(final List<Task> tasks){
        runOnUiThread(new Runnable() {

                @Override
                public void run() {
                      mAdapter = new TaskAdapter(tasks);
                      mTaskRV.setAdapter(mAdapter);
                }
        });


}

答案 2 :(得分:0)

首先让我们使用它,而更清楚。并且使用get text应该更好,因为它可以避免在其他情况下跳过标签等。

while (eventType != XmlPullParser.END_DOCUMENT) {
    if (eventType == XmlPullParser.START_TAG) {
        if (xpp.getName().equalsIgnoreCase("name")) {
            tasks.add(new Task(xpp.getText()));
        }
    }
    eventType = xpp.next();
}

List<Task> tasks = task.getTasks();中出现错误,这有助于https://stackoverflow.com/a/218510/2226796

此外,我没有得到这一部分:

Task task = new Task();
new Task().execute();