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.
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;
}