0

I am developing an Android app for booking. This is my first question on stackoverflow. So pardon me if I don't follow the rules exactly. I am stuck with this fatal error:

FATAL EXCEPTION: main


 Process: com.connectandroiddb.myapplication, PID: 26440
    android.os.NetworkOnMainThreadException
        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1147)
        at java.net.InetAddress.lookupHostByName(InetAddress.java:418)
        at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
        at java.net.InetAddress.getAllByName(InetAddress.java:215)
        at com.android.okhttp.HostResolver$1.getAllByName(HostResolver.java:29)
        at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:232)
        at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:124)
        at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:272)
        at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:211)
        at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:382)
        at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:332)
        at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:199)
        at com.example.myapplication.JSONParser.makeHttpRequest(JSONParser.java:65)
        at com.example.myapplication.MainActivity$GetProductDetails$1.run(MainActivity.java:144)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5254)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

I have borrowed the code from: https://androidhive.info/2012/05/how-to-connect-android-with-php-mysql/ Relevant code below: I am calling GetProductDetails() as below in

public void sendMessage(View view) {
.....
new GetProductDetails().execute(); 
......
}

which is in MainActivity.java

/**
     * Background Async Task to Get complete product details
     * */
class GetProductDetails extends AsyncTask<String, String, String> { 
        protected void onPreExecute() {
            super.onPreExecute();
        }
        /**
         * Getting product details in background thread
         * */
        protected String doInBackground(String... params) {

            // updating UI from Background Thread
            runOnUiThread(new Runnable() {
                public void run() {

                    JSONObject json = jsonParser.makeHttpRequest(
                            url_get_product_details, "GET");// Line 144

                }
            });
                     return null;
        }

                /**
         * After completing background task Dismiss the progress dialog
         * **/
                protected void onPostExecute(String file_url) {
                    }
    } 

These are the relevant portions from JSONParser:

private String readStream(InputStream is) {
        try {
            ByteArrayOutputStream bo = new ByteArrayOutputStream();
            int i = is.read();
            while(i != -1) {
                bo.write(i);
                i = is.read();
            }
            return bo.toString();
        } catch (IOException e) {
            return "";
        }
    }

        public JSONObject makeHttpRequest(String url, String method)
    {
 HttpURLConnection urlConnection = null;

        // Making HTTP request
        try {

            // check for request method
            if(method == "POST"){
                // request method is POST  CHECK


            }else if(method == "GET"){
                // request method is GET

            URL u = new URL("http://example.com/");
            urlConnection = (HttpURLConnection) u.openConnection();
            InputStream in = new BufferedInputStream(urlConnection.getInputStream()); //JSONParser.java:65
            json=readStream(in);
            }    
        }   
        catch (MalformedURLException ex) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
        } 
        catch (IOException ex) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
        }
        finally {
            if (urlConnection != null) {
                try {
                    urlConnection.disconnect();
                } catch (Exception ex) {
                    Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
                }       
        } 
        }
}

I have added internet permission in AndroidManifest.xml. Please help!!!. Thanks in advance,

1 Answers1

0

Your problem is in this part of the code:

protected String doInBackground(String... params) {

    // updating UI from Background Thread
    runOnUiThread(new Runnable() {
        public void run() {

            JSONObject json = jsonParser.makeHttpRequest(url_get_product_details, "GET");   
        }
    });
    return null;
}

As you can see, in the method doInBackground you are executing something on the UI thread. Android runs all the UI in the same UI thread, and you cannot execute any long running task (like a network request) on that thread, as the UI would remain freeze.

That is why people use async tasks or simple threads. If in the doInBackground method you execute runOnUiThread you are breaking that rule, and an exception NetworkOnMainThreadException raises.

Read the tutorial here on how to pass information between the background and UI using an AsyncTask. A tip, you need to use onPostExecute

droidpl
  • 5,872
  • 4
  • 35
  • 47
  • Thanks a lot for pointing me in the right direction. I am running the httpurlconnection on a background thread. Not on runOnUithread anymore. It works like a breeze. – Danny Joseph Mar 21 '19 at 07:03
  • Nice. Then don't forget to accept the answer with the tick, so the rest knows this is the correct one :) – droidpl Mar 22 '19 at 09:17