2013-07-15 41 views
1

嘿,一個新手來android編程和我正在這個項目上工作。 這個問題很長,所以這裏就是交易。在其他線程上執行方法的同步

我有延長GCMBaseIntentService這個GCMIntentService類和當消息從服務器到達時,GCMBroadcastReceiver可自動識別並調用GCMIntentService類重寫onMessage()方法。現在在onMessage正文中,我正在對SQLiteDatabase執行一些操作,並且我正在通過在onMessage主體內的ui線程中調用adapter.notifyDataSetChanged()來通知我的適配器進行列表視圖。

現在,如果超過2或3 gcm的消息同時傳到設備,應用程序會崩潰,因爲多個線程正在調用相同的onMessage()方法,並且正在搞亂我的數據庫和適配器。我想我需要在一次只能由一個線程使用的方法上使用synchronized關鍵字。

但自從我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 
    } 
} 
} 

回答

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. 
} 
} 
+0

我不明白你所謂的「線程」與bucle .. – delive

0

首先,onMessage()方法被執行每一次新的GCM消息到達(即使你不進你的應用程序,因爲我們註冊該接收器到清單文件中)。因此,獲取您的活動的上下文會導致您的應用程序崩潰(NullPointerException)。

現在,就您的問題而言,您可以維護一個跟蹤傳入的GCM消息的隊列。並且,在處理消息時,您可以檢查隊列中的條目並處理它們。爲此,您可以使用布爾值來標記是否有任何消息正在處理(標誌== true)。當(flag == false)時,你可以從隊列中取出下一個條目並處理它。

我希望它有用。

+0

@Abhishek ...如何實現你的建議隊列的事情嗎?請示例 – Sid

+0

還...如果我無法獲得我的mainActivity的上下文,我怎麼可以使用runOnUiThread方法? – Sid

+0

@Sid,爲此,您可以在您的活動中實現一個監聽器。 –

相關問題