Search code examples
androidnullpointerexceptionsdkandroid-adapterbaseadapter

BaseAdapter.getCount() throws null pointer exception while the referenced object is absolutely not null


I'm building both background server and android application for food-ordering project. There is a function that helps customers make sure whether the table is occupied or not. The logic is written in TableActivity.java which I will show down below. Basically the item to inflate the view is a ImageView and a TextView. ImageView is either vacant or occupied while TextView is the number of the table. The background code is okay that returns a json string that contains the table number and table flag(1 vacant;0 occupied). But the LogCat gave me null pointer exception. I'll be appreciated if you give some advice.

I use tomcat 7 as server software and servlet to handle the connection between client and database. Background is fine and I think the problem is in my android client codes. Android SDK version is 27.

public class TableActivity extends Activity {
    GridView gv;
    List<Table> list;
    MyAdapter myAdapter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.table);
        list = new ArrayList<Table>(); //Table is an Entity class 
        gv = findViewById(R.id.table_gridView);
        myAdapter = new MyAdapter();
        //init network
        String url = "http://10.0.2.2:8080/WL_Server/TableServlet";
        new MyTask().execute(url);
        gv.setAdapter(myAdapter);


    }

    /*@param: The url of server servlet
     Visit target url, gets the output of the server. The function returns a json that contains info of Tabletbl table.
    * */
    String doGetTableMsg(String url){
        String json = OkHttpUtil.doGet(url);
        return json;
    }


    //异步任务,处理网络请求
    class MyTask extends AsyncTask<String, Integer, String>{

        @Override
        protected String doInBackground(String... strings) {
            return doGetTableMsg(strings[0]);   
        }


        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            Gson gson = new Gson();
            Type type = new TypeToken<List<Table>>(){}.getType();
            list = gson.fromJson(s, type);  
            myAdapter.notifyDataSetChanged();
        }
    }

    class MyAdapter extends BaseAdapter {



        @Override
        public int getCount() {
            //This return sentence is where the exception happened. But this 
            // list object has been initiated and assigned with value already?
            return list.size();
        }

        @Override
        public Object getItem(int i) {
            return null;
        }

        @Override
        public long getItemId(int i) {
            return 0;
        }


        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            View view1;
            if (view == null){
                //Inflate a view from an XML resource.
                view1 = View.inflate(getApplicationContext(), R.layout.table_item, null);
            }else {
                view1 = view;
            }


            ImageView imageView1 = view1.findViewById(R.id.itemImageView1);
            TextView textView1 = view1.findViewById(R.id.itemTextView1);

            //Logic to decide whether table is vacant or not. Totally fine.
            Table table = list.get(i);
            int flag = table.getFlag();
            if (flag == 0){
                imageView1.setImageResource(R.drawable.kongwei);
            }else {
                imageView1.setImageResource(R.drawable.youren);
            }
            textView1.setText(table.getTid() + "");
            return view1;
        }
    }

}

I expect the emulator will show the view but it gave me null pointer exception like below:

java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference at xuming.com.wl_client.TableActivity$MyAdapter.getCount(TableActivity.java:82)

Line 82 is return list.size();

The normal reason that occurs this could be using [findViewById] instead of [View.findViewById] in getItem method but I've already used the latter one. Appreciated and if you need more codes I'll provide.


Solution

  • you should place your gv.setAdapter(myAdapter); within onPostExecute()

       @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            Gson gson = new Gson();
            Type type = new TypeToken<List<Table>>(){}.getType();
            list = gson.fromJson(s, type);  
            gv.setAdapter(myAdapter);
            myAdapter.notifyDataSetChanged();
        }
    

    and also change your getItem() and getItemId()to :

        @Override
        public Object getItem(int i) {
            return list.get(i);
        }
    
        @Override
        public long getItemId(int i) {
            return list.get(i).getId;
        }