在解析XML时,只有创建视图层次结构的原始线程才能触及其视图

时间:2017-01-05 23:04:41

标签: android xml listview

我已从RESTful服务中提取xml并将其置于XMLPullParser中。然后我尝试使用这些信息填充列表视图。我是XML解析的新手,不知道为什么它没有使用响应中的数据填充列表。

我的代码如下:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        context = getApplicationContext();

        listView = (ListView) findViewById(R.id.contactListView);

        OkHttpClient client = getUnsafeOkHttpClient();
        Request request = new Request.Builder()
                .url(myURL)
                .build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                final String responseData = response.body().string();
                InputStream stream = new ByteArrayInputStream(responseData.getBytes());
                List<PeepWithPic> peepWithPics;
                XMLPullParserHandler parserHandler = new XMLPullParserHandler();
                peepWithPics = parserHandler.parse(stream);
                ArrayAdapter<PeepWithPic> adapter = new ArrayAdapter<>(getApplicationContext(),
                        R.layout.contact_cardview_layout, peepWithPics);
                listView.setAdapter(adapter);


            }
        });

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

public class XMLPullParserHandler {
    List<PeepWithPic> peepWithPicList;
    private PeepWithPic peepWithPic;
    private String text;

    public XMLPullParserHandler() {
        peepWithPicList = new ArrayList<>();
    }

    public List<PeepWithPic> getPeepWithPicList() {
        return peepWithPicList;
    }

    public List<PeepWithPic> parse(InputStream is) {
        XmlPullParserFactory factory = null;
        XmlPullParser parser = null;
        try {
            factory = XmlPullParserFactory.newInstance();
            factory.setNamespaceAware(true);
            parser = factory.newPullParser();

            parser.setInput(is, null);

            int eventType = parser.getEventType();
            while (eventType != XmlPullParser.END_DOCUMENT) {
                String tagname = parser.getName();
                switch (eventType) {
                    case XmlPullParser.START_TAG:
                        if (tagname.equalsIgnoreCase("PeepWithPic")) {
                            // create a new instance of employee
                            peepWithPic = new PeepWithPic();
                        }
                        break;

                    case XmlPullParser.TEXT:
                        text = parser.getText();
                        break;

                    case XmlPullParser.END_TAG:
                        if (tagname.equalsIgnoreCase("PeepWithPic")) {
                            // add employee object to list
                            peepWithPicList.add(peepWithPic);
                        } else if (tagname.equalsIgnoreCase("First_name")) {
                            peepWithPic.setFirst_name(text);
                        } else if (tagname.equalsIgnoreCase("Last_name")) {
                            peepWithPic.setLast_name(text);
                        } else if (tagname.equalsIgnoreCase("Payroll_title")) {
                            peepWithPic.setPayroll_title(text);
                        /*} else if (tagname.equalsIgnoreCase("email")) {
                            peepWithPic.setEmail(text);*/
                        } /*else if (tagname.equalsIgnoreCase("type")) {
                            peepWithPic.set(text);
                        }*/
                        break;

                    default:
                        break;
                }
                eventType = parser.next();
            }

        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return peepWithPicList;
    }
}

1 个答案:

答案 0 :(得分:1)

当您尝试修改UI线程外部的视图时,会发生该错误。如果没有为哪一行引起问题的堆栈跟踪,我无法给出确定问题的确切答案。但是问题出现在这里:您正在onResponse调用中操纵UI。您可以尝试将代码更新为:

client.newCall(request).enqueue(new Callback() {
            Handler mainHandler = new Handler(context.getMainLooper());
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                final String responseData = response.body().string();
                InputStream stream = new ByteArrayInputStream(responseData.getBytes());

                mainHandler.post(new Runnable() {

                    @Override
                    public void run() {
                        List<PeepWithPic> peepWithPics;
                        XMLPullParserHandler parserHandler = new XMLPullParserHandler();
                        peepWithPics = parserHandler.parse(stream);
                        ArrayAdapter<PeepWithPic> adapter = new ArrayAdapter<>(getApplicationContext(),
                                R.layout.contact_cardview_layout, peepWithPics);
                        listView.setAdapter(adapter);
                    }
                });


            }
        });

但是,由于你还有XmlPullParser,如果解析它需要太长时间,你可能会得到一个ANR。理想情况下,您希望将listView调用移到onResponse之外,然后从XmlPullParser中执行与Handler mainHandler = new Handler(context.getMainLooper());类似的操作,将UI更新传递回主线程