我正试图在GcmListenerService中实现一个回调侦听器。我需要在收到新消息时刷新聊天对话。
我像往常一样继续,在主机活动和服务中设置侦听器,但当我的回调侦听器开始显示结果时,我得到了以下错误:
FATAL EXCEPTION: AsyncTask #1 java.lang.NullPointerException
at com.cerculdivelor.gcm.MyGcmListenerService.onMessageReceived(MyGcmListenerService.java:69)
at com.google.android.gms.gcm.GcmListenerService.zzq(Unknown Source)
at com.google.android.gms.gcm.GcmListenerService.zzp(Unknown Source)
at com.google.android.gms.gcm.GcmListenerService.zzo(Unknown Source)
at com.google.android.gms.gcm.GcmListenerService.zza(Unknown Source)
at com.google.android.gms.gcm.GcmListenerService$1.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:841)
可能出了什么问题,在服务内部使用回调可能是一种糟糕的方法吗??
GcmListenerService:
public class MyGcmListenerService extends GcmListenerService {
private static final String TAG = "MyGcmListenerService";
private SQLiteDataSource datasource;
newMessageListener mListener;
/**
* Called when message is received.
*
* @param from SenderID of the sender.
* @param data Data bundle containing message data as key/value pairs.
* For Set of keys use data.keySet().
*/
// [START receive_message]
@Override
public void onMessageReceived(String from, Bundle data) {
if (data.getString("notiftype") != null && data.getString("notiftype").equals("message")) {
datasource = new SQLiteDataSource(this);
datasource.open();
MessagesSetter message = new MessagesSetter();
message.setConversationId(data.getString("conversationId"));
message.setSenderfbid(data.getString("senderfbid"));
message.setSendername(data.getString("sendername"));
message.setProdname(data.getString("prodname"));
message.setMessage(data.getString("message"));
message.setTime(data.getString("timestamp"));
message.setAction(data.getString("action"));
Log.i("TAG", data.getString("message"));
datasource.addMessage(message);
showMessageNotification(data);
//refresh the conversation in ConversationActivity
mListener.newMessageArieved();
}
...
// Interface to send selected image's position for deletion
public void setNewMessageListener(newMessageListener mListener) {
this.mListener = mListener;
}
public static interface newMessageListener {
public void newMessageArieved ();
}
}
主机活动:
public class ConversationActivity extends AppCompatActivity implements MyGcmListenerService.newMessageListener {
private ListView listview;
private SQLiteDataSource datasource;
private Bundle extras;
private String myFbId;
private String senderFbId;
private String conversationId;
private EditText replyText;
private ImageView sendReplyBtn;
private HttpConActivity http;
private ArrayList<MessagesSetter> conversation;
private String myName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.conversation_layout);
Toolbar toolbar = (Toolbar) findViewById(R.id.messageToolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
SharedPreferences preferences = getSharedPreferences("user",
MODE_PRIVATE);
myFbId = preferences.getString("fbId", "");
myName = preferences.getString("name", "");
extras = getIntent().getExtras();
if (extras != null) {
conversationId = extras.getString("conversationId");
}
//set up the listener for new message arievals
MyGcmListenerService serv = new MyGcmListenerService();
serv.setNewMessageListener(this);
...
@Override
public void newMessageArieved() {
conversation = datasource.getConversation(conversationId);
ConversationListViewAdapter messAdapt = new ConversationListViewAdapter(this,
R.layout.conversation_row_layout, conversation);
listview.setAdapter(messAdapt);
Log.i("TAG", "NEW MESSAGE!");
}
我不完全确定在服务内部使用回调是否违反最佳实践,但在您的情况下,我会为MyGcmListenerService
创建一个构造函数,将侦听器作为参数。类似这样的东西:
public MyGcmListenerService(newMessageListener listener){
this.mListener = listener;
}
这样,您就可以在初始化服务时立即进行设置。不过,我还是会为听众保留setter,以防万一。然后在onMessageReceived
中,我只需要包含一个null检查器,以防没有侦听器集,如下所示:
if (mListener != null){
mListener.newMessageArieved();
} else {
Log.d(TAG, "No new message listener set.");
}
你的日志显示了一个NPE,但我不太确定是不是听众造成的。你有没有做一些测试(添加日志之类的东西)来验证NPE的确切原因?