android服务内部的回调侦听器不工作-致命异常:AsyncTask#1



我正试图在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的确切原因?

最新更新