BaseAdapter.getCount() 引用对象绝对不为空时抛出空指针异常
BaseAdapter.getCount() throws null pointer exception while the referenced object is absolutely not null
我正在为订餐项目构建后台服务器和 android 应用程序。
有一个功能可以帮助客户确定table是否被占用。逻辑写在 TableActivity.java 中,我将在下面展示。基本上,膨胀视图的项目是一个 ImageView 和一个 TextView。 ImageView要么空着,要么被占用,而TextView是table号。
后台代码没问题 returns 一个 json 包含
table 数字和 table 标志(1 个空缺;0 个占用)。但是 LogCat 给了我空指针异常。如果您能提供一些建议,我将不胜感激。
我使用tomcat7作为服务器软件和servlet来处理客户端和数据库之间的连接。背景很好,我认为问题出在我的 android 客户端代码中。
AndroidSDK 版本为 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],但我已经使用了后者。
非常感谢,如果您需要更多代码,我会提供。
您应该将 gv.setAdapter(myAdapter);
放在 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;
}
尝试以下操作:
@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
完成执行之后,并为您的适配器添加构造函数。
我正在为订餐项目构建后台服务器和 android 应用程序。 有一个功能可以帮助客户确定table是否被占用。逻辑写在 TableActivity.java 中,我将在下面展示。基本上,膨胀视图的项目是一个 ImageView 和一个 TextView。 ImageView要么空着,要么被占用,而TextView是table号。 后台代码没问题 returns 一个 json 包含 table 数字和 table 标志(1 个空缺;0 个占用)。但是 LogCat 给了我空指针异常。如果您能提供一些建议,我将不胜感激。
我使用tomcat7作为服务器软件和servlet来处理客户端和数据库之间的连接。背景很好,我认为问题出在我的 android 客户端代码中。 AndroidSDK 版本为 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],但我已经使用了后者。 非常感谢,如果您需要更多代码,我会提供。
您应该将 gv.setAdapter(myAdapter);
放在 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;
}
尝试以下操作:
@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
完成执行之后,并为您的适配器添加构造函数。