0

I am using XmlPullParser which parse file from server, of course I am doing it in another thread. I am using rxAndroid to work with threads, but it throws NetworkOnMainThread exception. Please help me.

public static List<ArticleModel> parseArticles(String get) {

    try {
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        factory.setNamespaceAware(true);
        XmlPullParser parser = factory.newPullParser();
        URL url = new URL(get);
        **parser.setInput(url.openStream(),null);** // HERE GOES THE EXCEPTION
        int eventType = parser.getEventType();
        while (eventType != XmlPullParser.END_DOCUMENT) {

            String tagname = parser.getName();
            switch (eventType) {
                case XmlPullParser.START_TAG:
                    if (tagname.equalsIgnoreCase("article")) {
                        // create a new instance of employee
                        articleModel =new ArticleModel();
                    }
                    break;

                case XmlPullParser.TEXT:
                    text = parser.getText();
                    break;
                case XmlPullParser.END_TAG:
                    if (tagname.equalsIgnoreCase("article")) {
                        // add employee object to list

                        articleModelList.add(articleModel);
                    }else if (tagname.equalsIgnoreCase("id")) {
                        articleModel.setId(text);

                    }  else if (tagname.equalsIgnoreCase("name")) {
                       articleModel.setName(text);
                    } else if (tagname.equalsIgnoreCase("image_url")) {
                        articleModel.setImage_url(text);
                    }
                    else if (tagname.equalsIgnoreCase("url")) {
                        articleModel.setUrl(text);
                    }
                    else if (tagname.equalsIgnoreCase("type")) {
                        articleModel.setType(text);
                    }
                    break;

                default:
                    break;
            }
            eventType = parser.next();
        }

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

    return articleModelList;
}

And this is my RX method:

public void getArticles(String get, final boolean needRefresh) throws IOException {

    Observable.just(XmlPullParserHanlder.parseArticles(get))
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<List<ArticleModel>>() {

                @Override
                public void onCompleted() {
                }

                @Override
                public void onError(Throwable e) {
                    Log.i("SIZE", "onNext: "+ e.toString());
                }

                @Override
                public void onNext(List<ArticleModel> articleModels) {

                }
            });
}
Jernej K
  • 1,602
  • 2
  • 25
  • 38
Anton Kazakov
  • 2,740
  • 3
  • 23
  • 34

2 Answers2

1

The problem is not with calling Rx methods from UI thread. The issue is you have do your network operation which is parseArticles() in non-UI thread.

You can try this approach -

public void getArticles(String get, final boolean needRefresh) throws IOException {

             Observable.create(new Observable.OnSubscribe<List< ArticleModel >>() {
                @Override
                public void call(Subscriber<? super List< ArticleModel >> subscriber) {

                        subscriber.onNext(parseArticles(get));
                        subscriber.onCompleted();

                }
            }).subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<List<ArticleModel>>() {

                @Override
                public void onCompleted() {
                }

                @Override
                public void onError(Throwable e) {
                    Log.i("SIZE", "onNext: "+ e.toString());
                }

                @Override
                public void onNext(List<ArticleModel> articleModels) {

                }
            });
        }
}
Anton Kazakov
  • 2,740
  • 3
  • 23
  • 34
Shadab Ansari
  • 7,022
  • 2
  • 27
  • 45
0

You use .subscribeOn(Schedulers.newThread())this is fine but this is for the result of Observable.just(XmlPullParserHanlder.parseArticles(get))and not for the XmlPullParserHanlder.parseArticles(get)method itself. Try something like this

Observable.just(get)
   .subscribeOn(Schedulers.newThread())
   .map(url -> XmlPullParserHanlder.parseArticles(url))
   .observeOn(AndroidSchedulers.mainThread())
   .subscribe(new Observer<List<ArticleModel>>() {

                @Override
                public void onCompleted() {
                }

                @Override
                public void onError(Throwable e) {
                    Log.i("SIZE", "onNext: "+ e.toString());
                }

                @Override
                public void onNext(List<ArticleModel> articleModels) {

                }
            });
Ralph Bergmann
  • 3,015
  • 4
  • 30
  • 61