Search code examples
javaandroidmultithreadingandroid-asynctaskandroid-networking

Android problems with URL connection and threading, and IllegalStateExceptions


This is the class that should allow me to connect to the url and to retrieve data from. It converts the JSON data in to String. Maybe there is a problem here and i can't see it. Im pretty new to this sort of programming.

public class NetworkConnection extends AsyncTask<String, Void, String> {
private static final String DEBUG_TAG = "HttpExample";




protected String doInBackground(String... urls) {
    try{
        return downloadUrl(urls[0]);
    } catch (IOException e) {
        return "Unable to retrieve Web Page";
    }
}

//Fetch the data from the URL
public String downloadUrl(String myurl) throws IOException {
    InputStream is = null;
    int len = 500;
    String text = new String();

    try {
        URL url = new URL(myurl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(10000 /* milliseconds */);
        conn.setConnectTimeout(15000 /* milliseconds */);
        conn.setRequestMethod("GET");
        conn.setDoInput(true);

        // Starts the query
        conn.connect();
        int response = conn.getResponseCode();
        Log.d(DEBUG_TAG, "The response is: " + response);
        is = conn.getInputStream();

        try {
                    BufferedReader br = new BufferedReader(
                            new InputStreamReader(
                                    conn.getInputStream()));
                    StringBuilder sb = new StringBuilder();
                    String line;
                    while ((line = br.readLine()) != null) {
                        sb.append(line + "\n");
                    }
                    br.close();
                    JSONArray data = new JSONArray(sb.toString());
                    for (int i = 0; i < data.length(); i++) {
                        JSONObject row = data.getJSONObject(i);
                        String klasse = row.getString("K_Nr");
                        String raum = row.getString("K_Raum");
                        text = text + klasse + ": " + raum + "\n";
                    }
        } catch (IOException e) {

        } catch (JSONException e) {
            e.printStackTrace();
        }


    } finally {
        if (is != null) {
            is.close();
        }
    }
    return text;
}

@Override
protected void onPostExecute(String s){
    super.onPostExecute(s);
}

}

This is the class in which the main thread UI is. here i try to access the url by the class Networkconnection. The problem is that i don't know how to thread correctly.

public class Start extends Activity {
// public String  URL = new String("http://10.0.2.2/?action=getKlassen");
// public String  URL = new String("http://127.0.0.1/webservice/ajax.php?action=getKlassen");
public String  URL;
NetworkConnection netCon;
public TextView testAusgabe;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Intent i = getIntent();
    String val = i.getStringExtra("Klasse");
    TextView ausgabe = (TextView) findViewById(R.id.ausgabe);
    testAusgabe = (TextView)findViewById(R.id.testAusgabe);
    netCon = new NetworkConnection();
    URL = new String("http://10.0.2.2/?action=getKlassen");
    ausgabe.setText(val);

}

public void myClickHandler(View view) {
    ConnectivityManager connMgr = (ConnectivityManager)
            getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
    if (networkInfo != null && networkInfo.isConnected()) {
        new NetworkConnection().execute(URL);
    } else {
        testAusgabe.setText("No network connection available.");
    }
}

public void onClick(View view){

}

public void zeigeListe_Click (View view) {

    startActivity(new Intent(this, KlassenView.class));
}
public void ladeDaten_Click(View view) {
    String data;

    data = netCon.doInBackground(URL);
    testAusgabe.setText(data);
}

}

Here we have the exception that is thrown. When i click on the button that should load the data the app crashes. It definitely has a threading problem but i don't understand the other exceptions. If someone could help that would be really great. Thanks in advance.

01-29 11:10:38.776 6648-6648/com.example.httptest E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.httptest, PID: 6648
java.lang.IllegalStateException: Could not execute method for android:onClick
 at android.view.View$DeclaredOnClickListener.onClick(View.java:4452)
 at android.view.View.performClick(View.java:5198)
 at android.view.View$PerformClick.run(View.java:21147)
 at android.os.Handler.handleCallback(Handler.java:739)
 at android.os.Handler.dispatchMessage(Handler.java:95)
 at android.os.Looper.loop(Looper.java:148)
 at android.app.ActivityThread.main(ActivityThread.java:5417)
 at java.lang.reflect.Method.invoke(Native Method)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.reflect.InvocationTargetException
 at java.lang.reflect.Method.invoke(Native Method)
 at android.view.View$DeclaredOnClickListener.onClick(View.java:4447)
 at android.view.View.performClick(View.java:5198) 
 at android.view.View$PerformClick.run(View.java:21147) 
 at android.os.Handler.handleCallback(Handler.java:739) 
 at android.os.Handler.dispatchMessage(Handler.java:95) 
 at android.os.Looper.loop(Looper.java:148) 
 at android.app.ActivityThread.main(ActivityThread.java:5417) 
 at java.lang.reflect.Method.invoke(Native Method) 
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
Caused by: android.os.NetworkOnMainThreadException
 at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273)
 at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:110)
 at libcore.io.IoBridge.connectErrno(IoBridge.java:154)
 at libcore.io.IoBridge.connect(IoBridge.java:122)
 at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:183)
 at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:452)
 at java.net.Socket.connect(Socket.java:884)
 at com.android.okhttp.internal.Platform.connectSocket(Platform.java:117)
 at com.android.okhttp.internal.http.SocketConnector.connectRawSocket(SocketConnector.java:160)
 at com.android.okhttp.internal.http.SocketConnector.connectCleartext(SocketConnector.java:67)
 at com.android.okhttp.Connection.connect(Connection.java:152)
 at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:185)
 at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128)
 at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341)
 at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
 at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
 at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:433)
 at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:114)
 at com.example.httptest.NetworkConnection.downloadUrl(NetworkConnection.java:50)
 at com.example.httptest.NetworkConnection.doInBackground(NetworkConnection.java:29)
 at com.example.httptest.Start.ladeDaten_Click(Start.java:62)
 at java.lang.reflect.Method.invoke(Native Method) 
 at android.view.View$DeclaredOnClickListener.onClick(View.java:4447) 
 at android.view.View.performClick(View.java:5198) 
 at android.view.View$PerformClick.run(View.java:21147) 
 at android.os.Handler.handleCallback(Handler.java:739) 
 at android.os.Handler.dispatchMessage(Handler.java:95) 
 at android.os.Looper.loop(Looper.java:148) 
 at android.app.ActivityThread.main(ActivityThread.java:5417) 
 at java.lang.reflect.Method.invoke(Native Method) 
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

Solution

  • Actually! You made a mistake in your code. You have to use
    netCon.execute(URL); instead of netCon.doInBackground(URL); And once execute() method called and you clicked again to start this method before completing the previous doInBackground() , exception would occur again. So do one thing: inside method onPreExecute(), prevent your button to clicked again and onPostExecute(), make it clickable again.

    So by doing this way you are preventing to create a new thread. Cheers!