当引用的对象绝对不为空时,BaseAdapter.getCount()会引发空指针异常

时间:2019-05-04 17:25:20

标签: android nullpointerexception sdk android-adapter baseadapter

我正在为食品订购项目构建后台服务器和android应用程序。 有一个功能可以帮助客户确定桌子是否被占用。逻辑写在TableActivity.java中,我将在下面显示。基本上,使视图膨胀的项目是ImageView和TextView。 ImageView是空置的还是已占用的,而TextView是表的编号。 后台代码还可以,它返回一个包含以下内容的json字符串: 表号和表标志(1个空位; 0个空位)。但是LogCat给了我空指针异常。如果您提供一些建议,我将不胜感激。

我使用tomcat 7作为服务器软件和servlet来处理客户端和数据库之间的连接。背景很好,我认为问题出在我的Android客户端代码中。 Android SDK版本是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;
        }
    }

}

我希望模拟器会显示视图,但是它给了我空指针异常,如下所示:

java.lang.NullPointerException:尝试在空对象引用上调用接口方法'int java.util.List.size()'         在xuming.com.wl_client.TableActivity $ MyAdapter.getCount(TableActivity.java:82)

第82行是return list.size();

发生这种情况的正常原因可能是在getItem方法中使用了[findViewById]而不是[View.findViewById],但我已经使用了后者。 非常感谢,如果您需要更多代码,我会提供。

2 个答案:

答案 0 :(得分:1)

尝试以下操作:

@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(); //remove; intialize after web request has a value

    String url = "http://10.0.2.2:8080/WL_Server/TableServlet";
    new MyTask().execute(url);
}

class MyTask extends AsyncTask<String, Integer, String>{
    ...
    ...
    ...

    @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);  //debug here, maybe gson is returning null

        //inizialize adapter whit list
        myAdapter = new MyAdapter(list);
        gv.setAdapter(myAdapter);
    }
}

class MyAdapter extends BaseAdapter {
        List<Table> adptList;

        public MyAdapter(List<Table> list){
            this.adptList = list;
        }

        @Override
        public int getCount() {
            return this.adptList.size();
        }
        ...
        ...
        ...
}

setAdpetr()完成执行后放置AsyncTask,并为适配器添加构造函数。

答案 1 :(得分:0)

您应将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(); }

getItem()

,还将getItemId() @Override public Object getItem(int i) { return list.get(i); } @Override public long getItemId(int i) { return list.get(i).getId; } 更改为:

{{1}}