在其他线程上执行方法的方法上的同步

时间:2013-07-15 19:36:02

标签: java android android-sqlite google-cloud-messaging

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

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

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

但是因为我的onMessage方法是一个重写方法,所以我决定制作另一个方法并在其上放置synchronized修饰符但是我再次需要从内部调用runOnUiThread()方法,因为我需要通知我的列表视图适配器的更改。

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

以下是我正在做的示例代码:

    @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
    }
}
}

2 个答案:

答案 0 :(得分:0)

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

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

我希望它很有用。

答案 1 :(得分: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.
}
}