Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am working on getting a JSONArray from a server, and then inserting it into a custom ListView. My code executes, but I have no idea why the program crashes before anything is displayed. I put some System.out.println(x) to see how far the console gets before it crashes, but it runs through all of them that I place?

Thanks in advance for any help!

public class MainActivity extends Activity
{
    private ListView list_view;
    private TrendingAdapter ta = null;

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

        //Create a ListView, defined in the activity_main.xml file
        this.list_view = (ListView) findViewById(R.id.list_view);
        System.out.println("1");

        //Display trending results
        try
        {
            get_trending();
            System.out.println("16");
        }
        catch (Exception e) 
        {
            e.printStackTrace();
        }       
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    //Async class...
    private class AsyncOp extends AsyncTask<String, Void, String>
    {
        @Override
        protected String doInBackground(String... strings)
        {
            System.out.println("5");
            JSONObject response_json = new JSONObject();
            JSONObject request_json = new JSONObject();

            //Take passed String[0] and turn into JSON
            try
            {
                request_json = new JSONObject(strings[0]);
            }
            catch (Exception e) 
            {
                e.printStackTrace();
            }

            //Send the JSON to the server and grab response
            try
            {
                System.out.println("6");
                HttpClient client = new DefaultHttpClient();
                String request_url = "http://SOME_IP/api/api.php?package=" + Uri.encode(request_json.toString(), null);
                HttpGet get_request = new HttpGet(request_url);
                HttpResponse get_response = client.execute(get_request);
                HttpEntity get_entity = get_response.getEntity();
                System.out.println("7");

                //Ensure a response before doing anything foolish
                if (get_entity != null)
                {
                    System.out.println("8");
                    String response = EntityUtils.toString(get_entity);
                    response_json = new JSONObject(response);
                    return response_json.toString();
                }               
            }
            catch (Exception e) 
            {
                e.printStackTrace();
            }

            //If we're here, the above response didn't work for some reason...
            return "crazy shit happened";
        }

        //What to do after the request is done...
        @Override
        protected void onPostExecute(String result)
        {
            System.out.println("9");
            //Call the resppnse parser function...
            try
            {
                server_response(result);
                System.out.println("14");
            }
            catch (Exception e) 
            {
                e.printStackTrace();
            }
        }       
    }

    private class TrendingAdapter extends ArrayAdapter<TrendingTopic>
    {
        private Context context;
        private int resource_id;
        private ArrayList<TrendingTopic> trending_list = new ArrayList<TrendingTopic>();

        public TrendingAdapter(Context context, int resource_id, ArrayList<TrendingTopic> trending_list)
        {
            super(context, resource_id, trending_list);
            this.resource_id = resource_id;
            this.context = context;
            this.trending_list = trending_list;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent)
        {
            ViewHolder holder = new ViewHolder(convertView);
            holder = (ViewHolder) convertView.getTag();
            holder.populateFrom(trending_list.get(position));

            return (convertView);
        }       
    }

    private class ViewHolder
    {
        public TextView topic_rank = null;
        public TextView topic_title = null;
        public TextView num_comments = null;

        public ViewHolder(View row)
        {
            this.topic_rank = (TextView) row.findViewById(R.id.topic_rank);
            this.topic_title = (TextView) row.findViewById(R.id.topic_title);
            this.num_comments = (TextView) row.findViewById(R.id.num_comments);
        }

        public void populateFrom(TrendingTopic topic)
        {
            this.topic_rank.setText(topic.rank);
            this.topic_title.setText(topic.body.substring(0, Math.min(topic.body.length(), 30)));
            this.num_comments.setText(topic.comments);
        }
    }

    public void get_trending() throws JSONException
    {
        System.out.println("2");
        JSONObject type = new JSONObject();
        JSONObject request = new JSONObject();

        type.put("type", "trending");
        request.put("key", "SOME_KEY");
        request.put("request", "info");
        request.put("info", type);

        System.out.println("3");
        AsyncOp operation = new AsyncOp();
        System.out.println("4");
        operation.execute(new String[] {request.toString()});
        System.out.println("15");
    }

    public void server_response(String json_string) throws JSONException
    {
        System.out.println("10");
        //Get JSON info into ArrayList
        JSONObject json = new JSONObject(json_string);
        JSONArray trending = json.getJSONArray("trending");
        ArrayList<TrendingTopic> trending_list = new ArrayList<TrendingTopic>();

        int x = 0;
        int end_of_list = trending.length();
        TrendingTopic topic = new TrendingTopic();
        while (x < end_of_list)
        {
            topic = new TrendingTopic(trending.getJSONObject(x));
            trending_list.add(topic);
            x++;
        }       

        System.out.println("11");
        //Display response into main ListView
        this.ta = new TrendingAdapter(this, android.R.layout.simple_list_item_1, trending_list);
        System.out.println("12");
        this.list_view.setAdapter(ta);
        System.out.println("13");
    }
}

And this is what is produced in the LogCat

05-14 03:11:16.410: I/System.out(1706): 1
05-14 03:11:16.410: I/System.out(1706): 2
05-14 03:11:16.410: I/System.out(1706): 3
05-14 03:11:16.410: I/System.out(1706): 4
05-14 03:11:16.420: I/System.out(1706): 15
05-14 03:11:16.420: I/System.out(1706): 16
05-14 03:11:16.430: I/System.out(1706): 5
05-14 03:11:16.430: I/System.out(1706): 6
05-14 03:11:16.561: D/gralloc_goldfish(1706): Emulator without GPU emulation detected.
05-14 03:11:17.771: I/System.out(1706): 7
05-14 03:11:17.771: I/System.out(1706): 8
05-14 03:11:17.840: D/dalvikvm(1706): GC_CONCURRENT freed 844K, 24% free 3177K/4164K, paused 5ms+9ms, total 36ms
05-14 03:11:18.320: I/System.out(1706): 9
05-14 03:11:18.320: I/System.out(1706): 10
05-14 03:11:18.470: D/dalvikvm(1706): GC_CONCURRENT freed 370K, 22% free 3278K/4164K, paused 12ms+21ms, total 101ms
05-14 03:11:18.491: I/System.out(1706): 11
05-14 03:11:18.500: I/System.out(1706): 12
05-14 03:11:18.500: I/System.out(1706): 13
05-14 03:11:18.500: I/System.out(1706): 14
05-14 03:11:18.510: D/AndroidRuntime(1706): Shutting down VM
05-14 03:11:18.510: W/dalvikvm(1706): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
05-14 03:11:18.542: E/AndroidRuntime(1706): FATAL EXCEPTION: main
05-14 03:11:18.542: E/AndroidRuntime(1706): java.lang.NullPointerException
05-14 03:11:18.542: E/AndroidRuntime(1706):     at com.example.actionbartutorial.MainActivity$ViewHolder.<init>(MainActivity.java:160)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at com.example.actionbartutorial.MainActivity$TrendingAdapter.getView(MainActivity.java:144)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.widget.AbsListView.obtainView(AbsListView.java:2159)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.widget.ListView.measureHeightOfChildren(ListView.java:1246)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.widget.ListView.onMeasure(ListView.java:1158)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.view.View.measure(View.java:15518)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.widget.RelativeLayout.measureChild(RelativeLayout.java:666)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:477)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.view.View.measure(View.java:15518)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4825)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.view.View.measure(View.java:15518)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.widget.LinearLayout.measureVertical(LinearLayout.java:847)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.view.View.measure(View.java:15518)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4825)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2176)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.view.View.measure(View.java:15518)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1874)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1089)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1265)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.view.Choreographer.doCallbacks(Choreographer.java:562)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.view.Choreographer.doFrame(Choreographer.java:532)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.os.Handler.handleCallback(Handler.java:725)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.os.Handler.dispatchMessage(Handler.java:92)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.os.Looper.loop(Looper.java:137)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at android.app.ActivityThread.main(ActivityThread.java:5041)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at java.lang.reflect.Method.invokeNative(Native Method)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at java.lang.reflect.Method.invoke(Method.java:511)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
05-14 03:11:18.542: E/AndroidRuntime(1706):     at dalvik.system.NativeStart.main(Native Method)
share|improve this question
add comment

2 Answers

up vote 1 down vote accepted

You haven't accounted for the fact that convertView is only a valid object once views start getting recycled. Initially, when the first views are created for the list, convertView is null, and your ViewHolder constructor doesn't handle a null parameter very gracefully.

Your ViewHolder pattern is a bit broken. When convertView is null, you have to inflate and return a new instance of the view to be used, and only in that instance create a new holder. You should have something more like:

ViewHolder holder;
if (convertView == null) {
    convertView = getLayoutInflater().inflate(resource_id, parent, false);
    holder = new ViewHolder(convertView);
    convertView.setTag(holder);
} else {
    holder = (ViewHolder) convertView.getTag();
}

holder.populateFrom(trending_list.get(position));

return convertView;
share|improve this answer
    
Thanks for the point in the right direction, but after this update to the code, I still get the same errors in the LogCat...? –  nathansizemore May 15 '13 at 1:35
add comment

The error was in using the android.R.layout.simple_list_item_1 instead of using the custom XML row that I had made. Although, I doubt it would of went much further without @Devunwired responding with the help, so I chose his for the answer...

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.