Android 从URL解析XML并卡在循环中
我试图从URL解析XML,但没有得到任何数据,调试时我发现自己陷入了Android 从URL解析XML并卡在循环中,android,xml,parsing,url,android-asynctask,Android,Xml,Parsing,Url,Android Asynctask,我试图从URL解析XML,但没有得到任何数据,调试时我发现自己陷入了while()循环。在我放弃之前,我的变量达到了160。我不明白为什么我被困在while循环中,而没有进入循环中的if语句 public class Task extends AsyncTask<Void,Void,Void> { private List<Task> tasks; public Task() { } @Override protected Void doInBackground(V
while()
循环。在我放弃之前,我的变量达到了160。我不明白为什么我被困在while循环中,而没有进入循环中的if语句
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;
}
代码List tasks=task.getTasks()中的下一行代码>正在给出错误:
java.lang.NullPointerException:尝试对空对象引用调用接口方法“int java.util.List.size()
我想我之所以会出现这个错误,是因为我没有等待AsyncTask
完成,也不知道该怎么做
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
/*Removed irrelevant code here*/
Task task = new Task();
new Task().execute();
List<Task> tasks = task.getTasks();
mAdapter = new TaskAdapter(tasks);
mTaskRV.setAdapter(mAdapter);
return view;
}
@覆盖
CreateView上的公共视图(布局、充气机、视图组容器、捆绑包保存状态){
/*删除了不相关的代码*/
任务=新任务();
新任务().execute();
List tasks=task.getTasks();
mAdapter=新任务适配器(任务);
mTaskRV.setAdapter(mAdapter);
返回视图;
}
您应该提供异步任务的侦听器,该任务将在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);
}
}
}
让类实现TaskListener
接口
在这个方法中,您将任务的结果提供给适配器
public void onTaskDone(final List<Task> tasks){
runOnUiThread(new Runnable() {
@Override
public void run() {
mAdapter = new TaskAdapter(tasks);
mTaskRV.setAdapter(mAdapter);
}
});
}
public void onTaskDone(最终列出任务){
runOnUiThread(新的Runnable(){
@凌驾
公开募捐{
mAdapter=新任务适配器(任务);
mTaskRV.setAdapter(mAdapter);
}
});
}
首先,让我们暂时使用它,这更清楚。使用get文本应该更好,因为它可以避免在其他情况下跳过标记等
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 tasks=task.getTasks()中找出该错误代码>这应该有帮助
我也没有得到这个部分:
Task task = new Task();
new Task().execute();
下面是一个TaskLoader示例和Loader的回调
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)
{
//
}
};
private LoaderManager.LoaderCallbacks MLLoaderCallbacks=新建LoaderManager.LoaderCallbacks()
{
@凌驾
公共加载器onCreateLoader(int-id,Bundle-args)
{
返回新的TaskLoader(getContext());
}
@凌驾
public void onLoadFinished(加载程序,列表数据)
{
mTaskRV.setAdapter(新任务适配器(数据));
}
@凌驾
公共void onLoaderReset(加载器)
{
//
}
};
还有任务加载器
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;
}
}
私有静态类TaskLoader扩展了AsyncTaskLoader
{
私有静态最终字符串标记=TaskLoader.class.getSimpleName();
私有列表mData=null;
公共任务加载器(上下文)
{
超级(上下文);
}
@凌驾
开始加载时受保护的void()
{
super.onStartLoading();
如果(mData!=null){
交付结果(mData);
}
if(takeContentChanged()| | mData==null){
力载荷();
}
}
@凌驾
公共无效交付结果(列表数据)
{
mData=数据;
super.deliverResult(数据);
}
@凌驾
公共列表加载背景()
{
试一试{
XmlPullParserFactory工厂=XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp=factory.newPullParser();
URL=新URL(“http://xxx");
InputStream in=null;
试一试{
in=url.openStream();
xpp.setInput(在“UTF-8”中);
返回任务(xpp);
}
最后{
if(in!=null){
in.close();
}
}
}
捕获(格式错误){
日志e(标签“loadInBackground”,e);
}
catch(XMLPullParseRexE){
日志e(标签“loadInBackground”,e);
}
捕获(IOE异常){
日志e(标签“loadInBackground”,e);
}
返回null;
}
私有列表解析任务(XmlPullParser xpp)
引发XmlPullParserException,IOException
{
ArrayList tasks=新建ArrayList();
int eventType=xpp.getEventType();
while(eventType!=XmlPullParser.END_文档){
if(eventType==XmlPullParser.START_标记){
if(xpp.getName().equalsIgnoreCase(“说明”)){
添加(新的TaskModel(xpp.nextText());
}
}
eventType=xpp.next();
}
返回任务;
}
}
您正在解析JSON或XML?代码与您的问题标题不匹配。是的,我正在解析XML,我不知道为什么要编写JSON。谢谢,现在编辑。从你的代码来看,它似乎卡在了第一步。案例条件启动文档被触发的原因您不要更改任何类似Xpp.next的内容,这样同样的事情会再次发生again@imsiso我删除了所有if语句,但保留了if(eventType==XmlPullParser.START_标记),为什么它永远不会成为现实,为什么我仍然被困在循环中?让我告诉你,我只使用逻辑,不知道你正在使用的代码。所以试试这个。如果(.start_tag){blabla}else{xpp.next();},那么如果您的条件不为真,那么xpp.next应该将您移动到下一个节点或其他位置,那么不会发生循环。如果这样做可以帮助你更进一步当我在onTaskDone上添加新代码时,onCreateView不会等待onTaskDone,因此视图将是emtpy,下面是新的onTaskDone代码:我知道你为什么会得到一个NPE,我的问题是我如何才能等待AsyncTask,所以我没有得到它。我使用新任务().execte();运行AsyncTask@neX不知道:|只是希望你能在我给你的链接中找到更多。你可以检查一下
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)
{
//
}
};
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;
}
}