Android SOAP XML 解析 ListView 错误

12 浏览
0 Comments

Android SOAP XML 解析 ListView 错误

我正在创建一个SOAP XML解析的ListView。

我正在添加(ksoap2-android-assembly-2.6.2-jar-with-dependencies.jar) jar文件。

我正在添加权限。

我正在使用ArrayList。

我不明白这个错误,请帮助我。

MainActivity.java

public class MainActivity extends ListActivity {
    // XML节点键
    static final String FORMMODEL = "FormModel";
    static final String TEXT1 = "Text1";
    static final String TEXT2 = "Text2";
    static final String TEXT3 = "Text3";
    private static final String METHOD_NAME = "HelloWorld";
    private static final String SOAP_ACTION = "http://tempuri.org/HelloWorld";
    private static final String NAMESPACE = "http://tempuri.org/";
    private static final String URL = "http://sygnetinfosol.com/webservice.asmx";
    // 可以从wsdl文件中获取这些值^
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        SoapObject request=new SoapObject(NAMESPACE, METHOD_NAME);
        request.addProperty("bSelected", true);
        SoapSerializationEnvelope sse=new SoapSerializationEnvelope(SoapEnvelope.VER11);
        sse.setOutputSoapObject(request);
        sse.dotNet=true;
        HttpTransportSE htse=new HttpTransportSE(URL);
        try {
            htse.call(SOAP_ACTION, sse);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        }
        SoapObject res=(SoapObject) sse.bodyIn;
        final ArrayList> valuesList = new ArrayList>();
        XMLParser parser = new XMLParser();
        String xml = parser.getXmlFromUrl(URL); // 获取XML
        Document doc = parser.getDomElement(xml); // 获取DOM元素
        NodeList nl = doc.getElementsByTagName(FORMMODEL);
        // 循环遍历所有的item节点 
        for (int i = 0; i < ((SoapObject) nl).getPropertyCount(); i++) {
            SoapObject  namesObject = (SoapObject) res.getProperty(i);
            for(int j=0;j map = new HashMap();
                Element e = (Element) nl.item(i);
                // 将每个子节点添加到HashMap的key => value中
                map.put(TEXT1, parser.getValue(e, sText1)); 
                map.put(TEXT2, parser.getValue(e, sText2));
                map.put(TEXT3, parser.getValue(e, sText3));
                System.out.println("MY SOAP RESPONE IS"+ res.getProperty(0).toString());
                // 将HashList添加到ArrayList中
                valuesList.add(map);
            }
        }    
        // 将menuItems添加到ListView中
        ListAdapter adapter = new SimpleAdapter(this, valuesList,R.layout.list_item,
            new String[] { TEXT1, TEXT2, TEXT3 }, new int[] {
                R.id.lat, R.id.long1, R.id.address });
        setListAdapter(adapter);
        ListView lv = getListView();
        System.out.println("MY SOAP RESPONE IS"+ res.getProperty(0).toString());
        // 在选择单个ListItem时启动新屏幕
        lv.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView parent, View view,int position, long id) {
                HashMap map = new HashMap();
                map = valuesList.get(position);
                // 启动新的意图
                Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class);
                in.putExtra(TEXT1, map.get(MainActivity.TEXT1));
                in.putExtra(TEXT2, map.get(MainActivity.TEXT2));
                in.putExtra(TEXT3, map.get(MainActivity.TEXT3));
                startActivity(in);
            }
        });
    }
}

LogCat

03-15 09:26:45.923: E/AndroidRuntime(3371): FATAL EXCEPTION: main
03-15 09:26:45.923: E/AndroidRuntime(3371): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.syg.abc/com.syg.abc.MainActivity}: android.os.NetworkOnMainThreadException
...

mainActivity.java

protected void onPostExecute(Void params) {
    ListAdapter adapter = new SimpleAdapter(this, valuesList,R.layout.list_item,
        new String[] { TEXT1, TEXT2, TEXT3 }, new int[] {
            R.id.lat, R.id.long1, R.id.address });
    setListAdapter(adapter);
    ListView lv = getListView();
    lv.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView parent, View view,int position, long id) {
            HashMap map = new HashMap();
            map = valuesList.get(position);
            // 启动新的意图
            Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class);
            in.putExtra(TEXT1, map.get(MainActivity.TEXT1));
            in.putExtra(TEXT2, map.get(MainActivity.TEXT2));
            in.putExtra(TEXT3, map.get(MainActivity.TEXT3));
            startActivity(in);
        }
    });
}

0
0 Comments

问题的出现原因是在主线程上进行网络请求。当应用程序在主线程上执行网络操作时,会抛出NetworkOnMainThreadException异常。这只会针对目标为Honeycomb SDK或更高版本的应用程序抛出。早期版本的SDK允许在主事件循环线程上进行网络操作,但这是不推荐的。

解决方法是使用AsyncTask来进行SOAP请求。在活动中,将SOAP请求放在AsyncTask的doInBackground方法中执行,并在onPostExecute方法中更新UI。

以下是修改后的代码:

public class MainActivity extends ListActivity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new SoapRequestTask().execute();
    }
    private class SoapRequestTask extends AsyncTask {
        //在UI线程上运行。显示进度对话框
        protected void onPreExecute() {
            //显示进度对话框
        }
        //在后台线程上运行。不要在此处更新UI
        protected Void doInBackground(Void... params) {
            //在此处进行SOAP请求
            SoapObject request=new SoapObject(NAMESPACE, METHOD_NAME);
            request.addProperty("bSelected", true);
            SoapSerializationEnvelope sse=new SoapSerializationEnvelope(SoapEnvelope.VER11);
            sse.setOutputSoapObject(request);
            sse.dotNet=true;
            HttpTransportSE htse=new HttpTransportSE(URL);
            try {
                htse.call(SOAP_ACTION, sse);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (XmlPullParserException e) {
                e.printStackTrace();
            }
            SoapObject res=(SoapObject) sse.bodyIn;
            final ArrayList> valuesList = new ArrayList>();
            XMLParser parser = new XMLParser();
            String xml = parser.getXmlFromUrl(URL); // 获取XML
            Document doc = parser.getDomElement(xml); // 获取DOM元素
            NodeList nl = doc.getElementsByTagName(FORMMODEL);
            //循环遍历所有item节点
            for (int i = 0; i < ((SoapObject) nl).getPropertyCount(); i++) {
                SoapObject namesObject = (SoapObject) res.getProperty(i);
                for(int j=0; j map = new HashMap();
                    Element e = (Element) nl.item(i);
                    // 将每个子节点添加到HashMap中,键=>值
                    map.put(TEXT1, parser.getValue(e, sText1)); 
                    map.put(TEXT2, parser.getValue(e, sText2));
                    map.put(TEXT3, parser.getValue(e, sText3));
                    System.out.println("MY SOAP RESPONE IS"+ res.getProperty(0).toString());
                    // 将HashList添加到ArrayList中
                    valuesList.add(map);
                }
            }
            return null;
        }
        //在UI线程上运行。在此处更新UI,显示数据在ListView中
        protected void onPostExecute(Void params) {
            //关闭进度对话框并更新UI
            ListAdapter adapter = new SimpleAdapter(MainActivity.this, valuesList, R.layout.list_item,
                    new String[] { TEXT1, TEXT2, TEXT3 }, new int[] { R.id.lat, R.id.long1, R.id.address });
        }
    }
}

另外,还可以使用RoboSpice作为替代方法。详情请查看链接:https://github.com/octo-online/robospice

希望对你有所帮助!

0
0 Comments

问题原因:在UI线程上进行长时间操作,会导致异常抛出。

解决方法:使用Android中的线程进行操作,可以参考上述链接中的资源。

0