0

2.3 でずっと機能していたコードがここにありますが、更新する必要があり、NetworkOnMainThreadException. Web サービスから xml を取得し、それを取り込んで配列リストに解析したいと考えています。ここにコードがあります

//Gets the xml from the url specified
String CallWebService(String url){
        String xml = null;
        try {
            // defaultHttpClient
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);

            HttpResponse httpResponse = httpClient.execute(httpGet);
            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;
}
//Parses the xml to get DOM element 
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 DOM
        return doc;
}
//Gets the child nodes of the xml
public String getValue(Element item, String str) {
    NodeList n = item.getElementsByTagName(str);
    return this.getElementValue(n.item(0));
}

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 || child.getNodeType() == Node.CDATA_SECTION_NODE){
                         return child.getNodeValue();
                     }
                 }
             }
         }
         return "";
 }

私にもgetChildElements方法があります。問題は、このメソッドを呼び出すときです。私はこのようにしていた:

String serviceURL = "http://webservice.example.com/";
String xml = CallWebService(serviceURL);
Document doc = GetDomElement(xml); // getting DOM element

NodeList nl = doc.getElementsByTagName("details");
getChildElements(nl); 

しかし、現在 4.1 ではこれを非同期で行う必要があり、その方法がわかりません。どんな助けでも大歓迎です。

編集

ここに私が持っているものがありますが、スレッドは開始しません

final String serviceURL = "urlString";
mHandler = new Handler() {
   @Override
   public void handleMessage(Message msg) {                             
     if(msg.what == JOB_COMPLETE) {
       String xml = (String) msg.obj;
       Document doc = GetDomElement(xml); // getting DOM element

       NodeList nl = doc.getElementsByTagName("details");
       getChildElements(nl); 
    }
    super.handleMessage(msg);
  }
};

Thread t = new Thread() {
    @Override
    public void run() {
       String xml = CallWebService(serviceURL);
       Message msg = Message.obtain(mHandler, JOB_COMPLETE, xml);
       msg.sendToTarget();
  }
};                                              
t.start();

編集

だから私は非同期の方法を試していますが、それでもうまくいきません。GetDomElement にまったくヒットしていません。これがコードです。

   //I call this in my onCreate()
   new getAppInfo().execute("http://webservice.example.com");

   private class getAppInfo extends AsyncTask<String, Void, String> {
    /** The system calls this to perform work in a worker thread and
      * delivers it the parameters given to AsyncTask.execute() */
    protected String doInBackground(String... urls) {
        return CallWebService(urls[0]);
    }

    /** The system calls this to perform work in the UI thread and delivers
      * the result from doInBackground() */
    protected void onPostExecute(String xml) {
        Document doc = GetDomElement(xml); // getting DOM element

        NodeList nl = doc.getElementsByTagName("details");
        getChildElements(nl); 
    }
}
4

4 に答える 4

0

たとえば、アクティビティ onCreate のメイン UI スレッドでハンドラを定義します。

private Handler mHandler;
private static int JOB_COMPLETE = 1;   

mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        if(msg.what == JOB_COMPLETE) {
            String xml = (String) msg.obj;
            // do whatever you want with that string
        }
        super.handleMessage(msg);
    }
 };

次に、すべての長いジョブをバックグラウンド スレッドで実行します

final String url = "...........";
Thread t = new Thread() {
    @Override
    public void run() {
        String xml = CallWebService(url);
        Message msg = Message.obtain(mHandler, JOB_COMPLETE, xml);
        msg.sendToTarget();
    }
};
t.start();
于 2012-08-24T13:08:44.483 に答える
0

AsyncTask を実装する必要があります。

http://developer.android.com/reference/android/os/AsyncTask.html

ところで、これはAndroid 3から必要です(よく覚えていれば)。

これをアプリに実装しました。ここでコードを参照できます: https://github.com/enrichman/roma-tre/blob/master/src/com/roma3/infovideo/utility/rss/RssTask.java

于 2012-08-24T13:01:16.547 に答える
0

この助けを願っています

http://www.techrepublic.com/blog/app-builder/using-androids-asynctask-to-handle-long-running-io/670?pg=2&tag=content;siu-container

于 2012-08-24T13:02:20.733 に答える
0

アプリケーションがメイン スレッドでネットワーク操作を実行しようとしたときにスローされる例外。

これは、Honeycom SDK 以降を対象とするアプリケーションに対してのみスローされます。以前のバージョンの SDK を対象とするアプリケーションは、メイン イベント ループ スレッドでネットワーキングを行うことができますが、 Android 開発者ページを参照してください。

非同期タスクを使用してネットワーク関連のタスクを実行するか、安全なスレッドを使用してみてください

于 2012-08-24T13:33:01.383 に答える