Android ListView 自定义Adapter 滑动时报空指针异常改怎么解决?

桐小目 2017-02-19 05:29:59
背景:在制作一个即时聊天的APP中,聊天界面聊天消息的显示我使用了ListView,并且使用了自定义的Adapter,获取到聊天记录之后ListView可以正常显示,但是一旦滑动就会报空指针异常。我查看了很多博客,都没有提到与这个相关或者类似的错误已经被这个错误逼疯了,希望有了解的大神能够给予指点。
具体相关代码如下:
自定义的Adapter:
public class ChatMessageAdapter extends BaseAdapter {
private LayoutInflater layoutInflater;
private List<MessageShow> messageShowList;


public ChatMessageAdapter(Context context, List<MessageShow> messageShowList){
layoutInflater = LayoutInflater.from(context);
this.messageShowList = messageShowList;
}

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

@Override
public Object getItem(int position) {
return messageShowList.get(position);
}

@Override
public int getItemViewType(int position) {
if(messageShowList.get(position).getMessageType()==0)
return 0;
else
return 1;
}
//Item类型的总数
@Override
public int getViewTypeCount() {
return 2;
}

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

@Override
public View getView(int position, View convertView, ViewGroup parent) {
MessageShow messageShow = messageShowList.get(position);
ViewHolder viewHolder = null;
if(convertView == null){
if(messageShow.getMessageType() == 0){
convertView = layoutInflater.inflate(R.layout.from_message_item,null);
viewHolder = new ViewHolder();
// viewHolder.imageView = (ImageView) convertView.findViewById(R.id.from_user_icons);
viewHolder.time = (TextView) convertView.findViewById(R.id.from_time);
viewHolder.message = (TextView) convertView.findViewById(R.id.from_message);
}
else{
convertView = layoutInflater.inflate(R.layout.to_message_item,null);
viewHolder = new ViewHolder();
// viewHolder.imageView = (ImageView) convertView.findViewById(R.id.to_user_icons);
viewHolder.time = (TextView) convertView.findViewById(R.id.to_time);
viewHolder.message = (TextView) convertView.findViewById(R.id.to_message);
}
}
else {
viewHolder = (ViewHolder) convertView.getTag();
}
System.out.println("我到了这里"+position);
System.out.println("我添加了适配器: "+messageShow.getContents());
// viewHolder.imageView.setImageResource(R.drawable.photo);
//报空指针异常的是这里
viewHolder.message.setText(messageShow.getContents());
viewHolder.time.setText(messageShow.getTime());
return convertView;
}

private final class ViewHolder{
// ImageView imageView;
TextView time;
TextView message;
}

mainActivity如下:
package cn.justwithme.withme.Activity;

import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.justwithme.withme.Entity.User;
import cn.justwithme.withme.R;
import cn.justwithme.withme.Utils.HttpUtils;
import cn.justwithme.withme.WebSocket.ClientService;

public class MainActivity extends AppCompatActivity {
//定义控件
private User currentUser;
private TextView userNameOutput;
private ListView listView;
private List<User> relations = new ArrayList<User>();
private List<Map<String,Object>> relationsView = new ArrayList<Map<String, Object>>();
private SimpleAdapter simpleAdapter;

//ServiceConnection
ClientService.ClientBinder binder;
private ServiceConnection serviceConnection = new ServiceConnection() {
//Activity与Service连接成功时回调此方法
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
System.out.println("-----------ClientService is binded!-----------");
binder = (ClientService.ClientBinder) service;
}
//Activity与Service断开连接时回调此方法
@Override
public void onServiceDisconnected(ComponentName name) {
System.out.println("-----------ClientService is unbinded!-----------");
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//绑定Service
bindClientService();
//初始化控件
initView();
//获取当前用户信息
getCurrentUserInfo();

}
@Override
protected void onDestroy(){
unBindClientService();
super.onDestroy();
}

//绑定Service
private void bindClientService(){
Intent intent = new Intent();
intent.setClass(MainActivity.this,ClientService.class);
bindService(intent,serviceConnection, Service.BIND_AUTO_CREATE);
}

//解除绑定Service
private void unBindClientService(){
unbindService(serviceConnection);
}

//初始化控件
private void initView(){
listView = (ListView) findViewById(R.id.relation_list);
userNameOutput = (TextView)findViewById(R.id.userName);
}


//获取当前用户的信息
private void getCurrentUserInfo(){
Intent intent = getIntent();
currentUser = (User)intent.getSerializableExtra("currentUser");
userNameOutput.setText(currentUser.getUserNickName());
getAllRelations(currentUser.getUserId());
}

//获取当前用户的所有好友
private void getAllRelations(final int userId){
final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message message) {
String response = (String)message.obj;
String jsonRelationList = JSON.parseObject(response).getString("relations");
relations = JSONArray.parseArray(jsonRelationList,User.class);
updateListView();
listenItems();
}
};
new Thread() {
public void run() {
String user = "userId="+userId;
String response = HttpUtils.doPostRequest("getRelations",user);
Message message = Message.obtain();
message.obj = response;
mHandler.sendMessage(message);
}
}.start();

}

//更新好友列表
private void updateListView(){
for(int i=0;i<relations.size();i++){
User user = relations.get(i);
Map<String,Object> listItem = new HashMap<String,Object>();
listItem.put("userNickName",user.getUserNickName());
if(user.getUserIsOnline() == 1)
listItem.put("userIsOnline","在线");
else
listItem.put("userIsOnline","离线");
relationsView.add(listItem);
}
simpleAdapter = new SimpleAdapter(this,relationsView,R.layout.relation_item,new String[]{String.valueOf(R.drawable.photo),"userNickName","userIsOnline"},new int[]{R.id.relation_icons,R.id.user_name,R.id.online_status});
listView.setAdapter(simpleAdapter);
}
//监听点击好友列表事件
private void listenItems(){
listView.setOnItemClickListener(new AdapterView.OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
System.out.println("我点击了"+position);
Intent intent = new Intent(MainActivity.this,ChatActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable("currentUser",currentUser);
bundle.putSerializable("chattingUser",(User)relations.get(position));
intent.putExtras(bundle);
startActivity(intent);
}
});
}
}

其中获取聊天记录我已经在控制台打印出来检查过了,没有错误,而ListView能够显示说明Apapter也不会有基本的错误,但是还是报空指针。我对错误的猜测如下:
虽然给的数据集可能有几十项,但是Adapter加载的时候只加载了当前显示的几项,后面的没加载,等我我滑动之后去加载的时候没加载到数据就报空指针了。但是这不太科学啊,我看了好多博客发现都没有专门说到这点,仔细检查代码也不知道应该怎么改,求指教。报错信息如下:
...全文
239 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
桐小目 2017-02-20
  • 打赏
  • 举报
回复
送分啦
头发还没秃a 2017-02-20
  • 打赏
  • 举报
回复
呵呵哒,蹭分来了
网络咖啡 2017-02-20
  • 打赏
  • 举报
回复
少了这样一行代码: convertView.setTag(item);//设置数据源
桐小目 2017-02-20
  • 打赏
  • 举报
回复
问题已解决,虽然论坛这里没人鸟我 = = ,但是问答有大神指点了,我把答案放出来。错误在于自定义Adapter里面重写的getView方法里面我在调用convertView的时候没有调用setTag,所以在convert不为空时,convert.getTag()就获取不到viewHolder,因此就会报空指针异常,这也就造成了第一页不会错但是一旦滑动就报错的现象,在if(convertView==null)里面添加一句convertView.setTag(viewHolder);就正常了,想来一般人应该不会犯这种错误吧,所以借鉴意义可能不是很大,但是还是把结论放上来吧,自我结贴。
桐小目 2017-02-19
  • 打赏
  • 举报
回复
报错信息如下:
I/System.out: 消息为:hello!
I/System.out: 消息为:wwww
I/System.out: 消息为:dsfsd 
I/System.out: 消息为:df 
I/System.out: 消息为:fg dfgfd 
I/System.out: 消息为:123
I/System.out: 消息为:123
I/System.out: 消息为:123
I/System.out: 消息为:12
I/System.out: 消息为:3
I/System.out: 消息为:123
I/System.out: 消息为:12
I/System.out: 消息为:hi
I/System.out: 消息为:你在干啥?
I/System.out: 消息为:在么
I/System.out: 消息为:驱蚊器无
I/System.out: 消息为:测试
D/dalvikvm: GC_FOR_ALLOC freed 25K, 4% free 9339K/9692K, paused 7ms, total 8ms
I/dalvikvm-heap: Grow heap (frag case) to 9.845MB for 640012-byte allocation
D/dalvikvm: GC_FOR_ALLOC freed <1K, 4% free 9963K/10320K, paused 20ms, total 20ms
I/System.out: [{'content':'hello!','from':3,'id':8,'isTransport':1,'time':'2017-02-12 15:39:54','to':1,'type':0},{'content':'wwww','from':1,'id':10,'isTransport':1,'time':'2017-02-12 16:06:06','to':3,'type':0},{'content':'dsfsd ','from':3,'id':12,'isTransport':1,'time':'2017-02-12 16:06:48','to':1,'type':0},{'content':'df ','from':3,'id':13,'isTransport':1,'time':'2017-02-12 16:06:49','to':1,'type':0},{'content':'fg dfgfd ','from':1,'id':89,'isTransport':1,'time':'2017-02-16 16:54:25','to':3,'type':0},{'content':'123','from':3,'id':91,'isTransport':1,'time':'2017-02-16 17:05:32','to':1,'type':0},{'content':'123','from':3,'id':92,'isTransport':1,'time':'2017-02-16 17:05:32','to':1,'type':0},{'content':'123','from':3,'id':93,'isTransport':1,'time':'2017-02-16 17:05:33','to':1,'type':0},{'content':'12','from':3,'id':94,'isTransport':1,'time':'2017-02-16 17:05:33','to':1,'type':0},{'content':'3','from':3,'id':95,'isTransport':1,'time':'2017-02-16 17:05:33','to':1,'type':0},{'content':'123','from':3,'id':96,'isTransport':1,'time':'2017-02-16 17:05:33','to':1,'type':0},{'content':'12','from':3,'id':97,'isTransport':1,'time':'2017-02-16 17:05:33','to':1,'type':0},{'content':'hi','from':1,'id':115,'isTransport':1,'time':'2017-02-17 01:27:18','to':3,'type':0},{'content':'你在干啥?','from':3,'id':154,'isTransport':1,'time':'2017-02-18 01:40:53','to':1,'type':0},{'content':'在么','from':3,'id':156,'isTransport':1,'time':'2017-02-18 22:36:55','to':1,'type':0},{'content':'驱蚊器无','from':3,'id':157,'isTransport':1,'time':'2017-02-18 22:47:32','to':1,'type':0},{'content':'测试','from':3,'id':159,'isTransport':1,'time':'2017-02-19 12:52:06','to':1,'type':0}]我到了这里0
I/System.out: 我添加了适配器: hello!
D/dalvikvm: GC_CONCURRENT freed 37K, 4% free 10087K/10472K, paused 3ms+3ms, total 19ms
I/System.out: 我到了这里1
I/System.out: 我添加了适配器: wwww
I/System.out: 我到了这里2
I/System.out: 我添加了适配器: dsfsd 
I/System.out: 我到了这里3
I/System.out: 我添加了适配器: df 
I/System.out: 我到了这里4
I/System.out: 我添加了适配器: fg dfgfd 
I/System.out: 我到了这里5
I/System.out: 我添加了适配器: 123
I/System.out: 我到了这里6
I/System.out: 我添加了适配器: 123
I/System.out: 我到了这里7
I/System.out: 我添加了适配器: 123
E/InputEventReceiver: Exception dispatching input event.
D/AndroidRuntime: Shutting down VM
W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0xa6160908)
E/AndroidRuntime: FATAL EXCEPTION: main
                  java.lang.NullPointerException
                      at cn.justwithme.withme.Adapaer.ChatMessageAdapter.getView(ChatMessageAdapter.java:84)
                      at android.widget.AbsListView.obtainView(AbsListView.java:2143)
                      at android.widget.ListView.makeAndAddView(ListView.java:1831)
                      at android.widget.ListView.fillDown(ListView.java:674)
                      at android.widget.ListView.fillGap(ListView.java:638)
                      at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4930)
                      at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3087)
                      at android.widget.AbsListView.onTouchEvent(AbsListView.java:3361)
                      at android.view.View.dispatchTouchEvent(View.java:7246)
上面的是我的打印输出,求大神指点!

80,337

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧