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

Callback listener inside android Service not working - FATAL EXCEPTION: AsyncTask #1

我正在尝试在我的 GcmListenerService 中实现回调侦听器。我需要在收到新消息时刷新聊天对话。

我照常进行,在主机 activity 和服务中设置侦听器,但是当我的回调侦听器开始显示结果时出现以下错误:

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

主持人Activity:

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 中,我只包含一个空检查器,以防万一没有设置侦听器,如下所示:

if (mListener != null){
                mListener.newMessageArieved();
            } else {
                Log.d(TAG, "No new message listener set.");
            }

您的日志显示 NPE,但我不太确定是否是监听器导致的。您是否进行了一些测试(添加日志和类似的东西)来验证到底是什么导致了 NPE?