0

我有一个 xml 解析器,它在模拟器中的 Android api 8 和 10 上运行良好(我的设备上有 api 10 并且运行良好)但尝试模拟更高的 api 并在 http 请求上给我错误。这是 Parser.class:

package com.muc.horoscop;

import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.util.Log;

public class XMLParser {


public XMLParser() {

}

/**
 * Getting XML from URL making HTTP request
 * @param url string
 * */


public String getXmlFromUrl(String url) {
    String xml = new String();

    try {
        // defaultHttpClient
        HttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);

//          httpPost.addHeader(BasicScheme.authenticate(
//          new UsernamePasswordCredentials("client_ro", "+_lklklkl*/544pF"),"UTF-8", false));  


        HttpResponse httpResponse = httpClient.execute(httpPost);
        HttpEntity httpEntity = httpResponse.getEntity();
        xml = EntityUtils.toString(httpEntity);

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    // return XML
    return xml;
}

/**
 * Getting XML DOM element
 * @param XML string
 * */
public Document getDomElement(String xml){
    Document doc = null;
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    try {

        DocumentBuilder db = dbf.newDocumentBuilder();

        InputSource is = new InputSource();
            is.setCharacterStream(new StringReader(xml));
            doc = db.parse(is); 

        } catch (ParserConfigurationException e) {
            Log.e("Error: ", e.getMessage());
            return null;
        } catch (SAXException e) {
            Log.e("Error: ", e.getMessage());
            return null;
        } catch (IOException e) {
            Log.e("Error: ", e.getMessage());
            return null;
        }

        return doc;
}

/** Getting node value
  * @param elem element
  */
 public final String getElementValue( Node elem ) {
     Node child;
     if( elem != null){
         if (elem.hasChildNodes()){
             for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() ){
                 if( child.getNodeType() == Node.TEXT_NODE  ){
                     return child.getNodeValue();
                 }
             }
         }
     }
     return "";
 }

 /**
  * Getting node value
  * @param Element node
  * @param key string
  * */
 public String getValue(Element item, String str) {     
        NodeList n = item.getElementsByTagName(str);        
        return this.getElementValue(n.item(0));
    }
}

这是 LogCat

12-31 11:23:31.223: D/AndroidRuntime(442): Shutting down VM
12-31 11:23:31.223: W/dalvikvm(442): threadid=1: thread exiting with uncaught exception (group=0x40014760)
12-31 11:23:31.243: E/AndroidRuntime(442): FATAL EXCEPTION: main
12-31 11:23:31.243: E/AndroidRuntime(442): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.muc.horoscop/com.muc.horoscop.AfisareHoroscop}: android.os.NetworkOnMainThreadException
12-31 11:23:31.243: E/AndroidRuntime(442):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1815)
12-31 11:23:31.243: E/AndroidRuntime(442):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1831)
12-31 11:23:31.243: E/AndroidRuntime(442):  at android.app.ActivityThread.access$500(ActivityThread.java:122)
12-31 11:23:31.243: E/AndroidRuntime(442):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1024)
12-31 11:23:31.243: E/AndroidRuntime(442):  at android.os.Handler.dispatchMessage(Handler.java:99)
12-31 11:23:31.243: E/AndroidRuntime(442):  at android.os.Looper.loop(Looper.java:132)
12-31 11:23:31.243: E/AndroidRuntime(442):  at android.app.ActivityThread.main(ActivityThread.java:4123)
12-31 11:23:31.243: E/AndroidRuntime(442):  at java.lang.reflect.Method.invokeNative(Native Method)
12-31 11:23:31.243: E/AndroidRuntime(442):  at java.lang.reflect.Method.invoke(Method.java:491)
12-31 11:23:31.243: E/AndroidRuntime(442):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
12-31 11:23:31.243: E/AndroidRuntime(442):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
12-31 11:23:31.243: E/AndroidRuntime(442):  at dalvik.system.NativeStart.main(Native Method)
12-31 11:23:31.243: E/AndroidRuntime(442): Caused by: android.os.NetworkOnMainThreadException
12-31 11:23:31.243: E/AndroidRuntime(442):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1077)
12-31 11:23:31.243: E/AndroidRuntime(442):  at java.net.InetAddress.lookupHostByName(InetAddress.java:477)
12-31 11:23:31.243: E/AndroidRuntime(442):  at java.net.InetAddress.getAllByNameImpl(InetAddress.java:277)
12-31 11:23:31.243: E/AndroidRuntime(442):  at java.net.InetAddress.getAllByName(InetAddress.java:249)
12-31 11:23:31.243: E/AndroidRuntime(442):  at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:136)
12-31 11:23:31.243: E/AndroidRuntime(442):  at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
12-31 11:23:31.243: E/AndroidRuntime(442):  at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
12-31 11:23:31.243: E/AndroidRuntime(442):  at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
12-31 11:23:31.243: E/AndroidRuntime(442):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
12-31 11:23:31.243: E/AndroidRuntime(442):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
12-31 11:23:31.243: E/AndroidRuntime(442):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
12-31 11:23:31.243: E/AndroidRuntime(442):  at com.muc.horoscop.XMLParser.getXmlFromUrl(XMLParser.java:52)
12-31 11:23:31.243: E/AndroidRuntime(442):  at com.muc.horoscop.AfisareHoroscop.onCreate(AfisareHoroscop.java:111)
12-31 11:23:31.243: E/AndroidRuntime(442):  at android.app.Activity.performCreate(Activity.java:4397)
12-31 11:23:31.243: E/AndroidRuntime(442):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048)
12-31 11:23:31.243: E/AndroidRuntime(442):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1779)
12-31 11:23:31.243: E/AndroidRuntime(442):  ... 11 more

以及创建列表的活动类:

public class AfisareHoroscop extends ListActivity {


    static final String KEY_ITEM = "item"; // parent node
    static final String KEY_ID = "id";
    static final String KEY_DATA = "data";
    static final String KEY_SCURT = "scurt";
    static final String KEY_DESC = "descriere";

    @Override
    public void onBackPressed() {
        finish();
    }

    public boolean isOnline() {
        ConnectivityManager cm =
            (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        if (netInfo != null && netInfo.isConnectedOrConnecting()) {
            return true;
        }
        return false;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);

        final String lala = getSharedPreferences("zodialui", MODE_PRIVATE).getString("zodia_consumator", "");
        final String url = "http://calina.mucomputers.eu/"+lala+".xml";
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_afisare_horoscop);
        //afisare titlu
        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.window_title);
        final String tit_gen = getApplicationContext().getResources().getString(R.string.titlu_gen);
        final TextView myTitleText = (TextView) findViewById(R.id.titlu);
        String titlul = new String(tit_gen+" "+lala);
        SpannableString spanString = new SpannableString(titlul);
        spanString.setSpan(new StyleSpan(Typeface.BOLD), 0, spanString.length(), 0);
        myTitleText.setText(spanString);
        ImageView semn_titlu = (ImageView) findViewById(R.id.imageView2);
        if (lala.equals("Balanta")) {
            semn_titlu.setImageResource(R.drawable.balanta);
        }else if (lala.equals("Berbec")){
            semn_titlu.setImageResource(R.drawable.berbec);
        }else if (lala.equals("Capricorn")){
            semn_titlu.setImageResource(R.drawable.capricorn);
        }else if (lala.equals("Fecioara")){
            semn_titlu.setImageResource(R.drawable.fecioara);
        }else if (lala.equals("Gemeni")){
            semn_titlu.setImageResource(R.drawable.gemeni);
        }else if (lala.equals("Leu")){
            semn_titlu.setImageResource(R.drawable.leu);
        }else if (lala.equals("Pesti")){
            semn_titlu.setImageResource(R.drawable.pesti);
        }else if (lala.equals("Rac")){
            semn_titlu.setImageResource(R.drawable.rac);
        }else if (lala.equals("Sagetator")){
            semn_titlu.setImageResource(R.drawable.sagetator);
        }else if (lala.equals("Scorpion")){
            semn_titlu.setImageResource(R.drawable.scorpion);
        }else if (lala.equals("Taur")){
            semn_titlu.setImageResource(R.drawable.taur);
        }else if (lala.equals("Varsator")){
            semn_titlu.setImageResource(R.drawable.varsator);
        }
        //afisare titlu

        if (isOnline() == true) {

        ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();

        XMLParser parser = new XMLParser();
        String xml = parser.getXmlFromUrl(url); // getting XML
        Document doc = parser.getDomElement(xml); // getting DOM element

        NodeList nl = doc.getElementsByTagName(KEY_ITEM);
        // looping through all item nodes <item>
        for (int i = 0; i < nl.getLength(); i++) {
            // creating new HashMap
            HashMap<String, String> map = new HashMap<String, String>();
            Element e = (Element) nl.item(i);

            // adding each child node to HashMap key => value
            map.put(KEY_DATA, parser.getValue(e, KEY_DATA));
            map.put(KEY_SCURT, parser.getValue(e, KEY_SCURT));
            map.put(KEY_DESC, parser.getValue(e, KEY_DESC));

            // adding HashList to ArrayList
            menuItems.add(map);
        }

        // Adding menuItems to ListView
        ListAdapter adapter = new SimpleAdapter(this, menuItems,
                R.layout.list_item,
                new String[] { KEY_SCURT, KEY_DATA, KEY_DESC }, new int[] {
                        R.id.scurt, R.id.data, R.id.descriere });

        setListAdapter(adapter);
        Collections.reverse(menuItems);

        // selecting single ListView item
        ListView lv = getListView();


        lv.setOnItemClickListener(new OnItemClickListener() {


            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                // getting values from selected ListItem

                String scurt = ((TextView) view.findViewById(R.id.scurt)).getText().toString();
                String data = ((TextView) view.findViewById(R.id.data)).getText().toString();
                String descriere = ((TextView) view.findViewById(R.id.descriere)).getText().toString();

                // Starting new intent
                Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class);
                in.putExtra(KEY_SCURT, scurt);
                in.putExtra(KEY_DATA, data);

                in.putExtra(KEY_DESC, descriere);
                startActivity(in);

            }

        });
        } else {

            Button btn = new Button(this);
            View.OnClickListener myhandler = new View.OnClickListener() {
                public void onClick(View v) {
                    Intent i = new Intent(AfisareHoroscop.this, AfisareHoroscop.class);  //your class
                    startActivity(i);
                    finish();
                }
              };
              btn.setOnClickListener(myhandler);
            btn.setText("Refresh");
            RelativeLayout.LayoutParams paramsd = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT ,LayoutParams.WRAP_CONTENT);
            paramsd.addRule(RelativeLayout.CENTER_IN_PARENT);
            paramsd.height = 60;
            paramsd.width = 60;
            btn.setLayoutParams(paramsd);
            addContentView(btn,paramsd); 
            Context context = getApplicationContext();
            String no_con = getResources().getString(R.string.no_connection);
            CharSequence text = no_con;
            int duration = Toast.LENGTH_SHORT;

            Toast toast = Toast.makeText(context, text, duration);
            toast.show();
        }

    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_afisare_horoscop, menu);
        return true;
    }
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_settings:
            Intent menu_set = new Intent (this, MainActivity.class);
            finish();
            startActivity(menu_set);
        return true;
        case R.id.menu_despre:
        startActivity(new Intent(this, DespreActivity.class));
        return true;
        default:
        return super.onOptionsItemSelected(item);
        }
    }
}

我花了 2 天的时间来了解发生了什么,这可能是因为我是初学者。谢谢!

4

1 回答 1

2

这个问题有两个解决方案,但第一个是很好的解决方案。

1)不要在主 UI 线程中编写网络调用,为此使用异步任务。

2) 在 setContentView(R.layout.activity_main); 之后将以下代码写入 MainActivity 文件;但这不是正确的方法。

if (android.os.Build.VERSION.SDK_INT > 9) {
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
}

并将下面的 import 语句放入您的 java 文件中。

import android.os.StrictMode;

有关更多信息,请参见下面的链接。

引起:android.os.NetworkOnMainThreadException

于 2012-12-31T09:36:55.863 回答