Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Android Build a Blog Reader Android App Adapting Data for Display in a List Cleaning Up Our Presentation

My BlogReader app is crashing 8 times in 10 launches and the LOGCAT shows NullPointer Exception and JSONException.

The point is that the json content is probably not being properly parsed as it shows some weird question mark like characters. Also the app crashes only 80%times and crashes only when active network is present. The app also crashes when the screen orientation changes. Thanks in advance.

The main Activity is package com.nagabhushan.blogreader;

import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL;

import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject;

import android.app.AlertDialog; import android.app.ListActivity; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.AsyncTask; import android.os.Bundle; import android.text.Html; import android.util.Log; import android.widget.ArrayAdapter; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast;

public class MainActivity extends ListActivity { protected String[] stringArray = { "Nagabhushan", "Blogger", "GSOC", "IIT", "Software", "Open Source Community", "Blogreader", "Sunshine", "Awesome app", "Hello reader", "Marvelous", "SQLite Database", "Rockstar" }; protected JSONObject myJSONObject = null; protected ProgressBar loadingApp;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    loadingApp = (ProgressBar) findViewById(R.id.progressBar1);     

    if (isConnectionAvailableAndConnected()) {
        loadingApp.setVisibility(ProgressBar.VISIBLE);

        MyBlogPostReaderTask myTask = new MyBlogPostReaderTask();
        myTask.execute();
    } else {
        loadingApp.setVisibility(ProgressBar.INVISIBLE);
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(getString(R.string.dialog_title));
        builder.setMessage("No active networks found");
        builder.setPositiveButton(getString(android.R.string.ok), null);
        AlertDialog dialog = builder.create();
        dialog.show();

        Toast.makeText(this, "No active networks available",
                Toast.LENGTH_SHORT).show();
    }

}

private boolean isConnectionAvailableAndConnected() {
    ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo info = manager.getActiveNetworkInfo();

    if (info != null && info.isConnected()) {
        return true;
    }

    else
        return false;

}

public void setUpTheListViewByExtractingJsonData() {
    loadingApp.setVisibility(ProgressBar.INVISIBLE);
    if (myJSONObject == null) {
        TextView tv = (TextView) getListView().getEmptyView();
        tv.setText("No items to display");

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(getString(R.string.dialog_title));
        builder.setMessage(getString(R.string.dialog_message));
        builder.setPositiveButton(getString(android.R.string.ok), null);
        AlertDialog dialog = builder.create();
        dialog.show();



    } else {

        try {
            JSONArray myJSONArray = myJSONObject.getJSONArray("posts");
            String[] stringArrayOfPosts = new String[myJSONArray.length()];
            for (int i = 0; i < myJSONArray.length(); i++) {
                JSONObject postJsonObject = myJSONArray.getJSONObject(i);
                String title = postJsonObject.getString("title");
                title = Html.fromHtml(title).toString();

                stringArrayOfPosts[i] = title;

                ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                        this, android.R.layout.simple_list_item_1,
                        stringArrayOfPosts);
                setListAdapter(adapter);

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

    }

}

private class MyBlogPostReaderTask extends
        AsyncTask<Object, Void, JSONObject> {
    private int responseCode;
    JSONObject parentBlockOfJSONText = null;

    @Override
    protected JSONObject doInBackground(Object... arg0) {
        try {
            URL url = new URL(
                    "http://blog.teamtreehouse.com/api/get_recent_summary/?count=20");
            HttpURLConnection connection = (HttpURLConnection) url
                    .openConnection();

            connection.connect();
            responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                InputStream stream = connection.getInputStream();
                Reader myReader = new InputStreamReader(stream);
                int lengthOfJSONText = connection.getContentLength();
                char[] myJSONChar = new char[lengthOfJSONText];
                myReader.read(myJSONChar);
                String actualJSONText = new String(myJSONChar);

                parentBlockOfJSONText = new JSONObject(actualJSONText);

            } else {

                Log.w("THE JSON TEXT", "NO INTERNET CONNECTION");
            }

        } catch (MalformedURLException e) {
            Log.e("Nagabhushan Alert", "Exception caught: ", e);
        } catch (IOException e) {
            Log.e("Nagabhushan Alert", "Exception caught: ", e);
        } catch (Exception e) {
            Log.e("Nagabhushan Alert", "Exception caught: ", e);
        }

        return parentBlockOfJSONText;
    }

    @Override
    protected void onPostExecute(JSONObject result) {

        myJSONObject = result;
        setUpTheListViewByExtractingJsonData();
        super.onPostExecute(result);

    }
}

}

The logcat error content is 01-31 20:40:15.772: E/Nagabhushan Alert(32034): Exception caught: 01-31 20:40:15.772: E/Nagabhushan Alert(32034): org.json.JSONException: Unterminated string at character 6230 of {"status":"ok","count":20,"count_total":1943,"pages":98,"posts":[{"id":24694,"url":"http:\/\/blog.teamtreehouse.com\/shaun-combined-passion-helping-youths-realise-full-potential-interest-web","title":"Shaun Applied His New Web Skills to Helping Youths Realise Their Full Potential","date":"2015-01-30 09:34:00","author":"Faye Bridge","thumbnail":null},{"id":24674,"url":"http:\/\/blog.teamtreehouse.com\/want-get-python-join-community","title":"Want to Get More Out of Python? Join the Community!","date":"2015-01-28 10:37:22","author":"Kenneth Love","thumbnail":"http:\/\/blog.teamtreehouse.com\/wp-content\/uploads\/2015\/01\/8572217654_57c261d9b3_z-150x150.jpg"},{"id":24677,"url":"http:\/\/blog.teamtreehouse.com\/skeleton-angularjs-fold-treehouse-show-episode-125","title":"Skeleton, AngularJS, The Fold | The Treehouse Show | Episode 125","date":"2015-01-27 09:30:58","author":"Chris Zabriskie","thumbnail":"http:\/\/blog.teamtreehouse.com\/wp-content\/uploads\/2015\/01\/Screen-Shot-2015-01-27-at-9.30.21-AM-150x150.png"},{"id":24675,"url":"http:\/\/blog.teamtreehouse.com\/new-treehouse-swift-python-future-web-apps","title":"New at Treehouse: Swift, Python, and Future of Web Apps","date":"2015-01-26 11:00:30","author":"Chris Zabriskie","thumbnail":"http:\/\/blog.teamtreehouse.com\/wp-content\/uploads\/2015\/01\/Screen-Shot-2015-01-26-at-10.56.34-AM-150x150.png"},{"id":24668,"url":"http:\/\/blog.teamtreehouse.com\/jessicas-new-coding-skills-opened-opportunities-work-freelancing-career","title":"New Coding Skills Opened Up Opportunities for Jessica at Work & For Her Freelancing Career","date":"2015-01-23 09:30:24","author":"Faye Bridge","thumbnail":"http:\/\/blog.teamtreehouse.com\/wp-content\/uploads\/2015\/01\/jess-150x150.jpg"},{"id":24665,"url":"http:\/\/blog.teamtreehouse.com\/intelligent-toys-guide-parents","title":"Intelligent Toys: A Guide for Parents","date":"2015-01-22 13:07:49","author":"Joy Kesten","thumbnail":"http:\/\/blog.teamtreehouse.com\/wp-content\/uploads\/2015\/01\/snap-150x150.jpg"},{"id":24654,"url":"http:\/\/blog.teamtreehouse.com\/create-simple-css-dropdown-menu","title":"How to Create a Simple CSS Dropdown Menu","date":"2015-01-21 11:01:01","author":"Guil Hernandez","thumbnail":"http:\/\/blog.teamtreehouse.com\/wp-content\/uploads\/2015\/01\/css-dropdown-150x150.png"},{"id":24661,"url":"http:\/\/blog.teamtreehouse.com\/javascript-frameworks-icons-text-images-treehouse-show-episode-124","title":"JavaScript Frameworks, Icons, Text on Images | The Treehouse Show | Episode 124","date":"2015-01-20 16:18:20","author":"Chris Zabriskie","thumbnail":"http:\/\/blog.teamtreehouse.com\/wp-content\/uploads\/2015\/01\/124-150x150.jpg"},{"id":24653,"url":"http:\/\/blog.teamtreehouse.com\/creating-today-extension-ios-8","title":"Creating a Today Extension with iOS 8","date":"2015-01-20 10:49:14","author":"Pasan Premaratne","thumbnail":"http:\/\/blog.teamtreehouse.com\/wp-content\/uploads\/2015\/01\/Screen-Shot-2015-01-20-at-10.48.38-AM-150x150.png"},{"id":24642,"url":"http:\/\/blog.teamtreehouse.com\/install-node-js-npm-linux","title":"How to Install Node.js and NPM on Linux","date":"2015-01-15 12:21:52","author":"Andrew Chalkley","thumbnail":"http:\/\/blog.teamtreehouse.com\/wp-content\/uploads\/2015\/01\/node-install-check-150x150.png"},{"id":24624,"url":"http:\/\/blog.teamtreehouse.com\/create-svg-sprite-sheet","title":"Create an SVG Sprite Sheet","date":"2015-01-14 12:48:49","author":"Guil Hernandez","thumbnail":"http:\/\/blog.teamtreehouse.com\/wp-content\/uploads\/2015\/01\/svg-sprites-150x150.png"},{"id":24637,"url":"http:\/����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� 01-31 20:40:15.775: E/AndroidRuntime(32034): FATAL EXCEPTION: main 01-31 20:40:15.775: E/AndroidRuntime(32034): java.lang.NullPointerException 01-31 20:40:15.775: E/AndroidRuntime(32034): at com.nagabhushan.blogreader.MainActivity.setUpTheListViewByExtractingJsonData(MainActivity.java:82) 01-31 20:40:15.775: E/AndroidRuntime(32034): at com.nagabhushan.blogreader.MainActivity$MyBlogPostReaderTask.onPostExecute(MainActivity.java:164) 01-31 20:40:15.775: E/AndroidRuntime(32034): at com.nagabhushan.blogreader.MainActivity$MyBlogPostReaderTask.onPostExecute(MainActivity.java:1) 01-31 20:40:15.775: E/AndroidRuntime(32034): at android.os.AsyncTask.finish(AsyncTask.java:631) 01-31 20:40:15.775: E/AndroidRuntime(32034): at android.os.AsyncTask.access$600(AsyncTask.java:177) 01-31 20:40:15.775: E/AndroidRuntime(32034): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644) 01-31 20:40:15.775: E/AndroidRuntime(32034): at android.os.Handler.dispatchMessage(Handler.java:107) 01-31 20:40:15.775: E/AndroidRuntime(32034): at android.os.Looper.loop(Looper.java:194) 01-31 20:40:15.775: E/AndroidRuntime(32034): at android.app.ActivityThread.main(ActivityThread.java:5371) 01-31 20:40:15.775: E/AndroidRuntime(32034): at java.lang.reflect.Method.invokeNative(Native Method) 01-31 20:40:15.775: E/AndroidRuntime(32034): at java.lang.reflThe point is that the json content is probably not being properly parsed as it shows some weird question mark like characters. Also the app crashes only 80%times and crashes only when active network is present. Thanks in advance.

6 Answers

I've googled a few results about 'Handling JSON unterminated string exception" and came across a load of TreehouseForum posts about this. Have a read though those - it seems that the content_length may not be as reliable as required.

Here's one to get you started :

https://teamtreehouse.com/forum/blogreader-app-json-exception

It seems that it has to something with the content-length and the treehouse blog api itself. Anyway, thanks for the help and research. I appreciate your help.

It seems that it has to something with the content-length and the treehouse blog api itself. Anyway, thanks for the help and research. I appreciate your help.

What line of code is LogCat saying the errors are at, and can you paste that whole file into here?

Do the column headings in your app match those in the JSON you are using?

When the app does not crash, the contents properly match those of json content, but when it crashes the logcat reads the json content which contains some awkward question mark like characters.

There's an unterminated string exception contained in the JSON. Did your connection fails part way through pulling the JSON data back?

It seems to but I am not sure. Is there a way to prevent this crash of app.

Also the json content shows those question marks starting at the same place everytime.

Hiya,

Can you try and edit the code a bit - if you add the three marks before and after the code, it'll format it a bit. If you add java after the first three, it'll really make it very clear.

One thing - your method isCOnnectionAvailableAndConnected looks like there's a brace missing. It is hard to tell, so I'll format it out below to check ...

private boolean isConnectionAvailableAndConnected() {
    ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo info = manager.getActiveNetworkInfo();

    if (info != null && info.isConnected()) {
        return true;
    }

    else
        return false;

}

That might be why your error seems linked with network availability.

Try editing your post with the three ` marks and we'll get a clearer view.

 package com.nagabhushan.blogreader;


public class MainActivity extends ListActivity { 
protected String[] stringArray = { "Nagabhushan", "Blogger", 
    "GSOC", "IIT", "Software", "Open Source Community", 
    "Blogreader", "Sunshine", "Awesome app", "Hello reader", 
    "Marvelous", "SQLite Database", "Rockstar" }; 

protected JSONObject myJSONObject = null; protected ProgressBar loadingApp;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    loadingApp = (ProgressBar) findViewById(R.id.progressBar1);     

    if (isConnectionAvailableAndConnected()) {
        loadingApp.setVisibility(ProgressBar.VISIBLE);

        MyBlogPostReaderTask myTask = new MyBlogPostReaderTask();
        myTask.execute();
    } else {
        loadingApp.setVisibility(ProgressBar.INVISIBLE);
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(getString(R.string.dialog_title));
        builder.setMessage("No active networks found");
        builder.setPositiveButton(getString(android.R.string.ok), null);
        AlertDialog dialog = builder.create();
        dialog.show();

        Toast.makeText(this, "No active networks available",
                Toast.LENGTH_SHORT).show();
    }

}

private boolean isConnectionAvailableAndConnected() {
    ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo info = manager.getActiveNetworkInfo();

    if (info != null && info.isConnected()) {
        return true;
    }

    else
        return false;

}

public void setUpTheListViewByExtractingJsonData() {
    loadingApp.setVisibility(ProgressBar.INVISIBLE);
    if (myJSONObject == null) {
        TextView tv = (TextView) getListView().getEmptyView();
        tv.setText("No items to display");

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(getString(R.string.dialog_title));
        builder.setMessage(getString(R.string.dialog_message));
        builder.setPositiveButton(getString(android.R.string.ok), null);
        AlertDialog dialog = builder.create();
        dialog.show();



    } else {

        try {
            JSONArray myJSONArray = myJSONObject.getJSONArray("posts");
            String[] stringArrayOfPosts = new String[myJSONArray.length()];
            for (int i = 0; i < myJSONArray.length(); i++) {
                JSONObject postJsonObject = myJSONArray.getJSONObject(i);
                String title = postJsonObject.getString("title");
                title = Html.fromHtml(title).toString();

                stringArrayOfPosts[i] = title;

                ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                        this, android.R.layout.simple_list_item_1,
                        stringArrayOfPosts);
                setListAdapter(adapter);

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

    }

}

private class MyBlogPostReaderTask extends
        AsyncTask<Object, Void, JSONObject> {
    private int responseCode;
    JSONObject parentBlockOfJSONText = null;

    @Override
    protected JSONObject doInBackground(Object... arg0) {
        try {
            URL url = new URL(
                    "http://blog.teamtreehouse.com/api/get_recent_summary/?count=20");
            HttpURLConnection connection = (HttpURLConnection) url
                    .openConnection();

            connection.connect();
            responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                InputStream stream = connection.getInputStream();
                Reader myReader = new InputStreamReader(stream);
                int lengthOfJSONText = connection.getContentLength();
                char[] myJSONChar = new char[lengthOfJSONText];
                myReader.read(myJSONChar);
                String actualJSONText = new String(myJSONChar);

                parentBlockOfJSONText = new JSONObject(actualJSONText);

            } else {

                Log.w("THE JSON TEXT", "NO INTERNET CONNECTION");
            }

        } catch (MalformedURLException e) {
            Log.e("Nagabhushan Alert", "Exception caught: ", e);
        } catch (IOException e) {
            Log.e("Nagabhushan Alert", "Exception caught: ", e);
        } catch (Exception e) {
            Log.e("Nagabhushan Alert", "Exception caught: ", e);
        }

        return parentBlockOfJSONText;
    }

    @Override
    protected void onPostExecute(JSONObject result) {

        myJSONObject = result;
        setUpTheListViewByExtractingJsonData();
        super.onPostExecute(result);

    }
}

Yes I found the answer. The culprit was actually the empty textView which I removed and replaced by an normal textView and the app now works in the most awesome way!!!!!!! Yehe.!!

Well done! Good work! :-)

Thanks Steve for your help!!