1

嘿,我是 android 编程的新手,我正在做这个项目。这个问题很长,所以这里是交易。

我扩展了这个 GCMIntentService 类GCMBaseIntentService,每当有消息从服务器到达时,它都会GCMBroadcastReceiver自动识别它并调用onMessage()GCMIntentService 类中的覆盖方法。现在在onMessage正文中,我正在对 进行一些操作,并通过在 onMessage 正文内的 ui 线程中SQLiteDatabase调用 来通知我的适配器以进行列表视图。adapter.notifyDataSetChanged()

现在,如果超过 2 或 3 条 gcm 消息同时发送到设备,则应用程序崩溃,因为多个线程正在调用相同的onMessage()方法,并且也弄乱了我的数据库和适配器。我想我需要在一次只能由一个线程使用的方法上使用同步关键字。

但由于我的onMessage方法是一个被覆盖的方法,我决定创建另一个方法并在其上放置同步修饰符,但我需要再次runOnUiThread()从它内部调用该方法,因为我需要通知对我的列表视图适配器的更改。

我只想问这样做是否是正确的方法,或者是否可以使用更简单的解决方案来解决我的问题?

这是 m 所做的示例代码:

    @Override
protected void onMessage(Context arg0, Intent intent) {

// called when a new cloud message has been received
Log.w("Service ", "Started");
dbh = new DatabaseHandler(this);
sld = dbh.getWritableDatabase();
who = this;

// processing json object
putDataFromJSON();
//other stuff
}

synchronized private void putDataFromJSON(){
//do some work on JSON Object
//complete work on JSON by putting in database
dbh.saveInDB();
//notify the adapter
((MainActivity) MainActivity.con).runOnUiThread(new Runnable() {
    @Override
    public void run() {
        adapter.notifyDataSetChanged();
        //do other stuffs as well
    }
}
}
4

2 回答 2

0

首先,每次有新的 GCM 消息到达时都会执行 onMessage() 方法(即使您没有进入您的应用程序,因为我们在清单文件中注册了这个接收器。)所以,获取您的活动的上下文是您的应用程序的原因崩溃(NullPointerException)。

现在,就您的问题而言,您可以维护一个队列来跟踪传入的 GCM 消息。而且,在处理消息时,您可以检查队列中的条目并处理它们。为此,您可以使用一个布尔值来标记当前是否正在处理任何消息(flag == true)。当(flag == false)时,您可以从队列中取出下一个条目并处理它..

我希望它有用。

于 2013-07-15T20:28:27.927 回答
0

我在这里写了一个虚拟代码,我认为它可以向您展示一个抽象架构..

public class GCMIntentService extends GCMBaseIntentService{
private static ArrayList<Message> messageQueue = new ArrayList<Message>();
private static boolean isProcessingMessage = false;

onMessage(Context context, Intent intent)
{
 if(isProcessingMessage)
   {
    Message currentMsg = new Message();//Create a instance of message and put it in arrayList

   }
   else{
         isProcessingMessage = true;
          for(int i  = 0; i < messageQueue.size(); i++)
             {//  Process all your messages in the queue here
               messageQueue.remove(i);
              }
              isProcessingMessage = false;
       }
}

 private class Message{

//In this class you can configure your message that you are going to queue.
}
}
于 2013-07-15T21:08:25.793 回答