1

Я получил эту ошибку, когда я пытался получить дату для списка, когда я искал ее, я обнаружил, что ее решение заключается в использовании async-задачи, но не знаю, как ее использовать, так как я могу использовать это в моем коде?android.os.NetworkOnMainThreadException. Нужно использовать async задачу для решения этой проблемы?

вот код:

package com.example.ms; 

import java.util.ArrayList; 
import java.util.HashMap; 

import org.w3c.dom.Document; 
import org.w3c.dom.Element; 
import org.w3c.dom.NodeList; 

import com.example.ms.XMLParser; 
import com.example.ms.LazyAdapter; 
import android.os.Bundle; 
import android.app.Activity; 
import android.view.Menu; 
import android.view.View; 
import android.view.Window; 
import android.widget.AdapterView; 
import android.widget.ListView; 
import android.widget.AdapterView.OnItemClickListener; 

public class PhotosActivity extends Activity { 

    ListView list; 
    LazyAdapter adapter; 
    static final String KEY_SONG = "song"; // parent node 
    static final String KEY_ID = "id"; 
    static final String KEY_TITLE = "title"; 
    static final String KEY_ARTIST = "artist"; 
    static final String KEY_DURATION = "duration"; 
    static final String KEY_THUMB_URL = "thumb_url"; 
    static final String URL = "http://api.androidhive.info/music/music.xml"; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 

     this.requestWindowFeature(Window.FEATURE_NO_TITLE); 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_photos); 

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

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

     NodeList nl = doc.getElementsByTagName(KEY_SONG); 

     // looping through all song nodes <song> 
       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_ID, parser.getValue(e, KEY_ID)); 
        map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE)); 
        map.put(KEY_ARTIST, parser.getValue(e, KEY_ARTIST)); 
        map.put(KEY_DURATION, parser.getValue(e, KEY_DURATION)); 
        map.put(KEY_THUMB_URL, parser.getValue(e, KEY_THUMB_URL)); 

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

     list = (ListView) findViewById(R.id.photoslist); 

     // Getting adapter by passing xml data ArrayList 
     adapter=new LazyAdapter(this, songsList);   
     list.setAdapter(adapter); 


     // Click event for single list row 
     list.setOnItemClickListener(new OnItemClickListener() { 

      @Override 
      public void onItemClick(AdapterView<?> parent, View view, 
        int position, long id) { 


      } 
     }); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.photos, menu); 
     return true; 
    } 

} 
+0

где ваш асинтезный код ?. http://developer.android.com/reference/android/os/AsyncTask.html – Raghunandan

+0

Я не знаю, как это сделать в точности, это мое первое приложение для Android. – Mohammad

+0

проверить документы и узнать, как закодировать asynctask, тогда, если вы столкнетесь с проблемами, вернитесь и спросите то же самое здесь. есть пример в ссылке, размещенной в моем предыдущем комментарии – Raghunandan

ответ

1

Да, вы должны запустить код Parsing, особенно вызов, где вы делаете parser.getXmlFromUrl HTTP вызова (URL); в отдельной нити. то есть в AsyncTask. Итак, скопируйте свой код на AsyncTask.doInBackground() и вернитесь из doInbackground() проанализированного списка. В AsyncTask.onPostExecution (List) вы получите свой разобранный список, и именно в этом случае для установки адаптера ListView этот синтаксис будет выполняться в основном потоке пользовательского интерфейса.

общественный класс PhotosActivity расширяет активность {

private XmlParserTask task; 

public void onCreate(Bundle saved){ 
    super.onCreate(Bundle saved); 
    // Do your UI setup 
    task = new XmlParserTask(); 
    task.execute(URL); 
} 


public void onDestroy(){ 
    super.onDestroy(); 
    // Avoid Memory leaks and android view not attached to window manager Exceptions 
    if (task != null) 
     task.cancel(true); 
} 


private class XmlParserTask extends AsyncTask<String, Void, List<YouSongType>> { 

    public List<YourSongType> doInBackground(String ... params){ 

     String url = params[0]; 

     List<YourSongType> resultList = new ArrayList<YourSongType>(); 

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

     NodeList nl = doc.getElementsByTagName(KEY_SONG); 

     // Add your xml parsed data in the list 
     resultList.add(); 

     return resultList; 
     } 


    public void onPostExecution(List<YourSongType> songsList){ 
     adapter=new LazyAdapter(this, songsList);   
     list.setAdapter(adapter); 
    } 


} 
+0

ok Я попробую. – Mohammad

+0

Я добавил небольшой фрагмент кода. Просто, чтобы дать вам идею. Важно отметить, что вам нужно отменить AsyncTask, если действие будет уничтожено (то есть пользователь нажимает кнопку «Назад»), так как AsyncTask будет запущен даже после того, как активность будет уничтожена, а затем попытается отправить результат обратно в Activity который больше не активен. Еще одна вещь, о которой вы, возможно, не знаете, начинается с Android 3.0 AsyncTask выполняется один за другим (и ждет, пока она не будет завершена, перед тем как начать следующий). Если вы хотите запустить AsyncTask параллельно, используйте executeOnExecutor() вместо execute() – sockeqwe

+0

Btw. не забудьте отметить правильное решение вашего вопроса: D – sockeqwe

0

Вы получаете эту ошибку, потому что вы пытаетесь получить данные из сети, и вы делаете это на главном потоке!

`String xml = parser.getXmlFromUrl(URL);` 

Как вы сказали, что вам нужно стрелять любой вид нити, чтобы избежать длительного процесса на mainthread, один из вариантов AsyncTask, используя AsyncTask прямо вперед, в основном у вас есть три метода onPreExecute() doInBackground() и onPostExecute()

onPreExecute() и onPostExecute() работать на UI потоке вы можете использовать их для отображения диалога, результат, или кормите список из ваших данных XML

doInBackground() пробега на Нето wrk thread, так что вы реализуете это для захвата xml с сервера, вы можете в onPostExcute() использовать делегирование для обновления списка из результата doInBackground()

Смежные вопросы