嘿,我是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
}
}
}
答案 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.
}
}