JsonReader running in thread crashes app

261 views Asked by At

My app is crashing unpredictably and I don't understand why. I'm using HttpURLConnection to retrieve a json file and I'm trying to use the JsonReader class to read from, and use that file. The trouble is that the application crashes after reading or doing anything to the instance of JsonReader.

I've read the input stream with scanner but that causes a similar problem. However when reading with the scanner I can print small amounts of json from the server. So the data from the server is probably making it into the JsonReader as well.

This is my code:

public class ConnectToServer implements Runnable {

private URL connectionUrl;
private MainActivity output;

public ConnectToServer(URL url, MainActivity mainActivity) {
    connectionUrl = url;
    output = mainActivity;
}

public void printError(String errorMessage){
    output.output(errorMessage);
}

public InputStream GetInputStream(){
    try {
        HttpURLConnection connection = (HttpURLConnection)connectionUrl.openConnection();
        InputStream inputStream = new BufferedInputStream(connection.getInputStream());
        if (inputStream == null){
            printError("Input stream is null");
        }
        return inputStream;
    } catch (IOException ex){
        printError("IO exception has been thrown");
    } catch (Exception ex){
        printError("Normal exception thrown: " + ex.getClass().getSimpleName());
    }
    return null;
}

@Override
public void run() {
    InputStream inputStream = GetInputStream();
    try {
        if (inputStream == null){
            printError("Input stream not initiated");
        } else {
            JsonReader reader = new JsonReader(new InputStreamReader(inputStream, "UTF-8"));
            printError(reader.toString());
            reader.close();
        }
    } catch (Exception ex){
        printError("Exception while printing input stream: " + ex.getClass().getSimpleName());
    }
    printError("Thread finished");
}

This gets run on a thread created in the main UI thread.

public void connect(){
    output("connect started");
    boolean success = true;
    try {
        URL url = new URL("http://geonews.azurewebsites.net/api/Location");
        serverConnection = new ConnectToServer(url,this);
        Thread thread = new Thread(serverConnection);
        thread.start();
    } catch (MalformedURLException ex){
        output("Messed up the URL");
        success = false;
    }
    if (success){
        output("Thread has been started");
    } else {
        output("exception was thrown while trying to run thread");
    }
}

Does anybody know why this code would be causing my app to crash? Even if it gets to "Thread finished" it will crash soon after.

Btw I realise I should be using AsyncTask but I've already gone down this track and I'd rather get this going first.

Logcat:

06-14 22:45:00.058    4032-4052/com.tomsapps.thomas.jsonreadertestapp E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-314
Process: com.tomsapps.thomas.jsonreadertestapp, PID: 4032
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
        at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6247)
        at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:867)
        at android.view.View.requestLayout(View.java:17364)
        at android.view.View.requestLayout(View.java:17364)
        at android.view.View.requestLayout(View.java:17364)
        at android.view.View.requestLayout(View.java:17364)
        at android.view.View.requestLayout(View.java:17364)
        at android.view.View.requestLayout(View.java:17364)
        at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:360)
        at android.view.View.requestLayout(View.java:17364)
        at android.widget.TextView.checkForResize(TextView.java:6798)
        at android.widget.TextView.updateAfterEdit(TextView.java:7693)
        at android.widget.TextView.handleTextChanged(TextView.java:7709)
        at android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:9440)
        at android.text.SpannableStringBuilder.sendTextChanged(SpannableStringBuilder.java:964)
        at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:515)
        at android.text.SpannableStringBuilder.append(SpannableStringBuilder.java:272)
        at android.text.SpannableStringBuilder.append(SpannableStringBuilder.java:33)
        at android.widget.TextView.append(TextView.java:3616)
        at android.widget.TextView.append(TextView.java:3603)
        at com.tomsapps.thomas.jsonreadertestapp.MainActivity.output(MainActivity.java:63)
        at com.tomsapps.thomas.jsonreadertestapp.ConnectToServer.printError(ConnectToServer.java:26)
        at com.tomsapps.thomas.jsonreadertestapp.ConnectToServer.run(ConnectToServer.java:74)
        at java.lang.Thread.run(Thread.java:818)
1

There are 1 answers

0
reidzeibel On BEST ANSWER

I believe your output method from MainActivity modifies a TextView, therefore triggering the exception.

A view hierarchy can only be changed from the "Main" thread, in this case, you might want to try looking into runOnUiThread , some resources on StackOverflow :

Hope this helps, good luck :)

Edit :

You might also want to use android Log instead of using TextView to display the errors.