2

I am new to Android and Java development , i am working as web developer and wanted to learn Android studio and java.

As always when learning new language , first thing I do is some database call, in this just JSON call.

Using httpURLConnection , i have found example online and it works in my main function when i run it in android studio, but when I put it inside button on click function and run my app on my mobile, my app crashes.

I have also added To AndroidManifest.xml inside manifest tags.

Here is error i get

11-22 19:47:46.354 24975-24975/com.example.adis.myapp I/System.out: I am here//////////////////////////////////////////
11-22 19:47:46.494 24975-24975/com.example.adis.myapp D/AndroidRuntime: Shutting down VM
11-22 19:47:46.494 24975-24975/com.example.adis.myapp W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x41659e00)
11-22 19:47:46.514 24975-24975/com.example.adis.myapp E/AndroidRuntime: FATAL EXCEPTION: main

                 Process: com.example.adis.myapp, PID: 24975
                    java.lang.IllegalStateException: Could not execute method for android:onClick
                        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
                ive Method)
                     Caused by: java.lang.reflect.InvocationTargetException
                        at java.lang.reflect.Method.invokeNative(Native Method)
                        at java.lang.reflect.Method.invoke(Method.java:515)
                        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
                        at android.view.View.performClick(View.java:4457) 
                        at android.view.View$PerformClick.run(View.java:18491) 
                        at android.os.Handler.handleCallback(Handler.java:733) 
                        at android.os.Handler.dispatchMessage(Handler.java:95) 
                        at android.os.Looper.loop(Looper.java:136) 
                        at android.app.ActivityThread.main(ActivityThread.java:5333) 
                        at java.lang.reflect.Method.invokeNative(Native Method) 
                        at java.lang.reflect.Method.invoke(Method.java:515) 
                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:895) 
                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:711) 
                        at dalvik.system.NativeStart.main(Native Method) 
                     Caused by: android.os.NetworkOnMainThreadException
                        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1148)
                        at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
                        at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
                        at java.net.InetAddress.getAllByName(InetAddress.java:214)
                        at com.android.okhttp.internal.Dns$1.getAllByName(Dns.java:28)
                        at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:216)
                        at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:122)
                        at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:292)
                        at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)
                        at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)
                        at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:345)
                        at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:296)
                        at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:503)
                        at com.example.adis.myapp.MainActivity.loginFunction(MainActivity.java:85)
                        at java.lang.reflect.Method.invokeNative(Native Method) 
                        at java.lang.reflect.Method.invoke(Method.java:515) 
                        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) 
                        at android.view.View.performClick(View.java:4457) 
                        at android.view.View$PerformClick.run(View.java:18491) 
                        at android.os.Handler.handleCallback(Handler.java:733) 
                        at android.os.Handler.dispatchMessage(Handler.java:95) 
                        at android.os.Looper.loop(Looper.java:136) 
                        at android.app.ActivityThread.main(ActivityThread.java:5333) 
                        at java.lang.reflect.Method.invokeNative(Native Method) 
                        at java.lang.reflect.Method.invoke(Method.java:515) 
                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:895) 
                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:711) 
                        at dalvik.system.NativeStart.main(Native Method) 
11-22 19:47:46.524 923-1275/? W/ActivityManager:   Force finishing activity com.example.adis.myapp/.MainActivity

Here is my onClick function

public void loginFunction(View view) throws IOException, JSONException {


    System.out.println("I am here//////////////////////////////////////////");
    try {

        URL url = new URL("http://echo.jsontest.com/insert-key-here/insert-value-here/key/value");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setRequestProperty("Accept", "application/json");

        if (conn.getResponseCode() != 200) {
            throw new RuntimeException("Failed : HTTP error code : "
                    + conn.getResponseCode());
        }

        BufferedReader br = new BufferedReader(new InputStreamReader(
                (conn.getInputStream())));

        String output;
        System.out.println("Output from Server .... \n");
        while ((output = br.readLine()) != null) {
            System.out.println(output);
        }

        conn.disconnect();

    } catch (MalformedURLException e) {

        e.printStackTrace();

    } catch (IOException e) {

        e.printStackTrace();

    }



}

Be harsh on me if you see some stupid mistake even java beginner should see, because i don't .

Thank you for stopping by :)

noitse
  • 1,045
  • 9
  • 27
  • Don't write network call in Main UI Thread, Use Async Task for that.Have a look at this elaborate sample. https://androidkennel.org/android-networking-tutorial-with-asynctask/ – John Nov 22 '16 at 19:04
  • As I said, I tested it if it returns json in main function only in android studio , and then moved it to on click. Ill take a look and your example right away :) Thank you for your time – noitse Nov 22 '16 at 19:07
  • Remove the method and print some logs in the click.On click of the button you would be able to see the Logs.Once you have your asynctask running you will see the that the issue is not with the click but as shown Caused by: android.os.NetworkOnMainThreadException.Since your new i would like you to read this as well.You will get a very clear picture. http://simpledeveloper.com/network-on-main-thread-error-solution/ – John Nov 22 '16 at 19:18

2 Answers2

3

You're not allowed to make a network connection on the main thread since this can freeze the UI thread and make your app unresponsive. That is why the exception is thrown.

You can make the button fire off a new thread or AsyncTask to complete the action.

Example: How to fix android.os.NetworkOnMainThreadException?

Community
  • 1
  • 1
mWhitley
  • 453
  • 7
  • 14
  • It works , just one question , now when i call my class that goes to DB for example new databaseCall().execute("test","databaseString"); How do i get response in my onClick function where i called it? – noitse Nov 22 '16 at 19:34
  • 1
    You can override the onPostExecute method of the AsyncTask class to perform the action you want in the UI since this method runs on the UI thread. – mWhitley Nov 22 '16 at 19:40
3
  1. Add this to your AndroidManifest.xml before Application tag:-

    <uses-permission android:name="android.permission.INTERNET"/> <application ..... </application>

  2. Even on trivial internet connection HTTP requests can take huge time thus freezing the Main UI thread. What you can do is start a new AsyncTask when button is hit.

    Put the code in separate class like :-

    public class HTTPRequestTask extends AsyncTask<Void, Void, Void> {
    
    @Override
    protected Void doInBackground(Void... params){
    System.out.println("I am   here//////////////////////////////////////////");
    try {
    URL url = new URL("http://echo.jsontest.com/insert-key-here/insert-value-here/key/value");
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("GET");
    conn.setRequestProperty("Accept", "application/json");
    
    if (conn.getResponseCode() != 200) {
        throw new RuntimeException("Failed : HTTP error code : "
                + conn.getResponseCode());
    }
    
    BufferedReader br = new BufferedReader(new InputStreamReader(
            (conn.getInputStream())));
    
    String output;
    System.out.println("Output from Server .... \n");
    while ((output = br.readLine()) != null) {
        System.out.println(output);
    }
    
    conn.disconnect();
    
    } catch (MalformedURLException e) {
    
       e.printStackTrace();
    
    } catch (IOException e) {
    
       e.printStackTrace();
    
    }
    

    And modify the onClickButton like :-

    OnButtonclick(...){ ... HTTPRequestTask testTask =new HTTPRequestTask(); testTask.execute(); ...}

    PS - I have named the new class as HTTPRequestTask. You can choose your own name.

Shubham Gupta
  • 159
  • 1
  • 14