2015-05-14 2 views
0

Я пытаюсь создать rss-ридер для своего приложения, проблема в том, когда я пытаюсь отобразить мой фрагмент, не работает и выдает исключение и не работает.Исключение пытается создать RSS Reader?

Я пытаюсь следовать этому примеру: https://androidresearch.wordpress.com/2012/01/21/creating-a-simple-rss-application-in-android/

Как я мог это сделать?

RSS Reader Фрагмент

public class RSSReaderFrag extends Fragment implements AdapterView.OnItemClickListener{ 
    private final String TAG = getClass().getSimpleName() + "->"; 
    private ProgressDialog progress; 

    //listas 
    private List headlines; 
    private List links; 
    private ListView listRSS; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.rss_feed, container, false); 

     listRSS = (ListView)view.findViewById(R.id.listRSS); 
     listRSS.setOnItemClickListener(this); 


     return view; 
    } 



    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 

     new AsyncTask<Void, Void, Void>(){ 
      @Override 
      protected Void doInBackground(Void... params) { 
       init(); 
       return null; 
      } 
     }.execute(); 
    } 




    /** init RSS */ 
    private void init(){ 
     // Initializing instance variables 
     headlines = new ArrayList(); 
     links = new ArrayList(); 

     try { 
      URL url = new URL("http://feeds.pcworld.com/pcworld/latestnews"); 

      XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); 
      factory.setNamespaceAware(false); 
      XmlPullParser xpp = factory.newPullParser(); 

      // We will get the XML from an input stream 
      xpp.setInput(getInputStream(url), "UTF_8"); 

     /* We will parse the XML content looking for the "<title>" tag which appears inside the "<item>" tag. 
     * However, we should take in consideration that the rss feed name also is enclosed in a "<title>" tag. 
     * As we know, every feed begins with these lines: "<channel><title>Feed_Name</title>...." 
     * so we should skip the "<title>" tag which is a child of "<channel>" tag, 
     * and take in consideration only "<title>" tag which is a child of "<item>" 
     * 
     * In order to achieve this, we will make use of a boolean variable. 
     */ 
      boolean insideItem = false; 

      // Returns the type of current event: START_TAG, END_TAG, etc.. 
      int eventType = xpp.getEventType(); 
      while (eventType != XmlPullParser.END_DOCUMENT) { 
       if (eventType == XmlPullParser.START_TAG) { 

        if (xpp.getName().equalsIgnoreCase("item")) { 
         insideItem = true; 
        } else if (xpp.getName().equalsIgnoreCase("title")) { 
         if (insideItem) 
          headlines.add(xpp.nextText()); //extract the headline 
        } else if (xpp.getName().equalsIgnoreCase("link")) { 
         if (insideItem) 
          links.add(xpp.nextText()); //extract the link of article 
        } 
       }else if(eventType==XmlPullParser.END_TAG && xpp.getName().equalsIgnoreCase("item")){ 
        insideItem=false; 
       } 

       eventType = xpp.next(); //move to next element 
      } 

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

     // Binding data 
     ArrayAdapter adapter = new ArrayAdapter(getView().getContext(), android.R.layout.simple_list_item_1, headlines); 
     listRSS.setAdapter(adapter); 
    } 

    private InputStream getInputStream(URL url) { 
     try { 
      return url.openConnection().getInputStream(); 
     } catch (IOException e) { 
      return null; 
     } 
    } 


    @Override 
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
     Uri uri = Uri.parse((String)links.get(position)); 
     Intent intent = new Intent(Intent.ACTION_VIEW, uri); 
     startActivity(intent); 
    } 
} 

Исключение

05-14 09:09:58.086 21617-22201/br.com.williarts.radios.provincia E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1 
    java.lang.RuntimeException: An error occured while executing doInBackground() 
      at android.os.AsyncTask$3.done(AsyncTask.java:299) 
      at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352) 
      at java.util.concurrent.FutureTask.setException(FutureTask.java:219) 
      at java.util.concurrent.FutureTask.run(FutureTask.java:239) 
      at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080) 
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573) 
      at java.lang.Thread.run(Thread.java:841) 
    Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 
      at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6818) 
      at android.view.ViewRootImpl.focusableViewAvailable(ViewRootImpl.java:3335) 
      at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:681) 
      at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:681) 
      at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:681) 
      at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:681) 
      at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:681) 
      at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:681) 
      at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:681) 
      at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:681) 
      at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:681) 
      at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:681) 
      at android.view.View.setFlags(View.java:9397) 
      at android.view.View.setFocusableInTouchMode(View.java:6168) 
      at android.widget.AdapterView.checkFocus(AdapterView.java:720) 
      at android.widget.ListView.setAdapter(ListView.java:471) 
      at br.com.williarts.radios.provincia.frags.NoticiasFrag.init(NoticiasFrag.java:136) 
      at br.com.williarts.radios.provincia.frags.NoticiasFrag.access$000(NoticiasFrag.java:36) 
      at br.com.williarts.radios.provincia.frags.NoticiasFrag$1.doInBackground(NoticiasFrag.java:70) 
      at br.com.williarts.radios.provincia.frags.NoticiasFrag$1.doInBackground(NoticiasFrag.java:67) 
      at android.os.AsyncTask$2.call(AsyncTask.java:287) 
      at java.util.concurrent.FutureTask.run(FutureTask.java:234) 
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080) 
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573) 
            at java.lang.Thread.run(Thread.java:841) 
+0

запустить 'listRSS.setAdapter (адаптер);' на нити ui – Blackbelt

ответ

1

Вы должны переместить эту часть кода вне doInBackground() функции и запустить его в UI Thread:

// Binding data 
ArrayAdapter adapter = new ArrayAdapter(getView().getContext(), android.R.layout.simple_list_item_1, headlines); 
listRSS.setAdapter(adapter);` 

в onPostExecute()

Перемещение только listRSS.setAdapter(adapter); является также достаточно, но для ради клиренса перемещения Adapter creation слишком

1

как уже отмечалось, вы не можете обновить поток пользовательского интерфейса из метода doInBackground в качестве AsyncTask (выполняется в другой поток) быстрое решение заменить:

// Binding data 
    ArrayAdapter adapter = new ArrayAdapter(getView().getContext(), android.R.layout.simple_list_item_1, headlines); 
    listRSS.setAdapter(adapter); 

с:

runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 
      listRSS.setAdapter(adapter); 
     } 
});