0

I'm getting the "android.os.NetworkOnMainThreadException" even though I'm not running anything network related in my main thread. How can I fix this?

I actually tried the code inside Eclipse and it worked just fine, but not in Android Studio where I'm developing the app itself.

Testclass.java:

package com.*****.*****;



        import android.graphics.Bitmap;
        import android.os.AsyncTask;
        import android.view.View;

        import java.io.*;
        import java.net.*;
        import java.util.*;
        import javax.xml.xpath.*;
        import javax.xml.namespace.*;
        import org.xml.sax.InputSource;
        import javax.xml.parsers.DocumentBuilderFactory;
        import org.w3c.dom.Document;

abstract class Testclass {


    public static class NamespaceResolver implements NamespaceContext {
        private Document document;

        public NamespaceResolver(Document doc) {
            document = doc;
        }

        public String getNamespaceURI(String prefix) {
            if (prefix.equals("")) {
                return document.lookupNamespaceURI(null);
            } else {
                return document.lookupNamespaceURI(prefix);
            }
        }

        public String getPrefix(String namespaceURI) {
            return document.lookupPrefix(namespaceURI);
        }

        public Iterator<String> getPrefixes(String namespaceURI) {
            return null;
        }
    }

    public static String downloadString(String url) throws Exception {
        StringBuilder sb = new StringBuilder();
        try (BufferedReader r = new BufferedReader(new InputStreamReader(new URL(url).openStream(), "UTF-8"))) {
            String line;
            while ((line = r.readLine()) != null) {
                sb.append(line + "\n");
            }
        }
        return sb.toString();
    }

    public static Document createDocumentFromString(String xml) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        return factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
    }

    static String value;

    public static String result() {

        try {
            String url = "http://opendata.fmi.fi/wfs/fin?service=WFS&version=2.0.0&request=GetFeature&storedquery_id=fmi::observations::mareograph::timevaluepair&fmisid=134223&";

            String xml = downloadString(url);
            Document document = createDocumentFromString(xml);
            XPath xpath = XPathFactory.newInstance().newXPath();
            xpath.setNamespaceContext(new NamespaceResolver(document));

            String time = xpath.evaluate("//wml2:MeasurementTimeseries[@gml:id='obs-obs-1-1-WATLEV']/wml2:point[last()]//wml2:time", document);
            value = xpath.evaluate("//wml2:MeasurementTimeseries[@gml:id='obs-obs-1-1-WATLEV']/wml2:point[last()]//wml2:value", document);
            System.out.format("time = %s; value = %s\n", time, value);
            return value;
        } catch (Exception e) {
            return "FAIL: " + e.toString();
        }
    }

}

Output when run in android studio: "null" and also throws "android.os.NetworkOnMainThreadException"

Output when run in Eclipse: "-97.0" (correct output)

ישו אוהב אותך
  • 28,609
  • 11
  • 78
  • 96
Japsu
  • 41
  • 5

2 Answers2

1

You need to use Asyn Task for networking purposes. A simple example is given in below link Async task in android

Tamir Abutbul
  • 7,301
  • 7
  • 25
  • 53
Pravin Yadav
  • 337
  • 3
  • 12
1

You need to run network related tasks on another thread, something like this:

Thread mThread = new Thread(new Runnable() {
@Override
public void run() {
    try  {
        //Put your code that you want to run in here
    } catch (Exception e) {
        e.printStackTrace();
    }
  }

Now, if you are not sure what causing this you can check your error log, it will guid you to the line that caused this problem.

Another thing that you can do is to add custom logs/prints with the error description, later on, you can check those logs to see if any of them called (if yes this means that you were getting error)

Tamir Abutbul
  • 7,301
  • 7
  • 25
  • 53
  • Yeah, I checked the error log and it actually didn't have anything related to this. Basically now I just need to find the spot that produces the error and run it inside the other thread. – Japsu May 04 '19 at 12:43
  • Yes, if the error log was not helpful just add error logs and check them out – Tamir Abutbul May 04 '19 at 12:45
  • what's the easiest way to add an error log? I'm new to java and still learning. – Japsu May 04 '19 at 12:55
  • Check [this](https://stackoverflow.com/questions/16780294/how-to-print-to-the-console-in-android-studio) – Tamir Abutbul May 04 '19 at 12:58
  • If this was helpful please accept the answer so other developers could assist this as well in the future. – Tamir Abutbul May 04 '19 at 13:00
  • Will accept it but seems like I don't get any additional info about the error/exception even tho I created a custom error log. This is all I get: `2019-05-04 16:04:40.184 9423-9423/com.******.***** D/EXCEPTIONFAIL: android.os.NetworkOnMainThreadException` – Japsu May 04 '19 at 13:07
  • If you have custom log simply check from where this log was called and put that code into another thread. – Tamir Abutbul May 04 '19 at 13:09
  • It was called from here [https://gyazo.com/8371c90102ecf08562f6c12f3eb6be65], should I then move the whole thread inside another thread..? I'm a bit confused right now haha. – Japsu May 04 '19 at 13:13
  • The link is broken, just move your code lines that are causing this problem – Tamir Abutbul May 04 '19 at 13:15