2013-06-21 52 views
0

我希望有人能夠清楚我的代碼中發生了什麼。我有一段代碼可以讀取和寫入我的數據庫,這個數據庫既可以從服務中運行,也可以從我的活動中運行。無論是從服務還是活動中調用,我都需要這段代碼進行線程安全。因此,我把類的代碼塊是並提出了靜態鎖定的對象保持它線程,你可以在下面的代碼塊見:Android靜態變量在服務方面不同於活動

synchronized(AnalyticsMessages.sync_lock){ 
       Log.v("mixpanel", "locking off of: "+AnalyticsMessages.sync_lock.toString()); 
       String[] eventsData = mDbAdapter.generateDataString(table); 
       if (eventsData != null) { 
        String lastId = eventsData[0]; 
        String rawMessage = eventsData[1]; 
        HttpPoster poster = getPoster(mEndpointHost, mFallbackHost); 
        HttpPoster.PostResult eventsPosted = poster.postData(rawMessage, endpointUrl); 

        if (eventsPosted == HttpPoster.PostResult.SUCCEEDED) { 
         logAboutMessageToMixpanel("Posted to " + endpointUrl); 
         logAboutMessageToMixpanel("Sent Message\n" + rawMessage); 
         //Log.v("mixpanel", "Sent Message\n" + rawMessage); 
         mDbAdapter.cleanupEvents(lastId, table); 
         Log.v("mixpanel", "removing id: "+lastId); 
        } 
        else if (eventsPosted == HttpPoster.PostResult.FAILED_RECOVERABLE) { 
         // Try again later 
         if (!hasMessages(FLUSH_QUEUE)) { 
          sendEmptyMessageDelayed(FLUSH_QUEUE, mFlushInterval); 
         } 
        } 
        else { // give up, we have an unrecoverable failure. 
         mDbAdapter.cleanupEvents(lastId, table); 
        } 
       } 
      } 

sync_lock在這樣AnalyticsMessages定義:

private static final Object sync_lock = new Object(); 

這顯然沒有正確鎖定,因此與toString的日誌。日誌告訴我,我似乎有兩個不同的sync_lock變量(因爲它在內存中打印一個地址)。我應該指出,AnalyticsMessages被實例化這樣的:

public static AnalyticsMessages getInstance(Context messageContext) { 
    synchronized (sInstances) { 
     Context appContext = messageContext.getApplicationContext(); 
     AnalyticsMessages ret; 
     if (! sInstances.containsKey(appContext)) { 
      if (MPConfig.DEBUG) Log.d(LOGTAG, "Constructing new AnalyticsMessages for Context " + appContext); 
      ret = new AnalyticsMessages(appContext); 
      sInstances.put(appContext, ret); 
     } 
     else { 
      if (MPConfig.DEBUG) Log.d(LOGTAG, "AnalyticsMessages for Context " + appContext + " already exists- returning"); 
      ret = sInstances.get(appContext); 
     } 
     return ret; 
    } 
} 

什麼,似乎是想上的是,當服務傳遞本身AnalyticsMessages.getInstance的背景下,我結束了一個sync_lock變量,但是當一個我的活動作爲背景在這裏傳遞,我最終得到一個不同的?這是否意味着android服務使用與主進程不同的類加載器?有沒有解決方法?我會認爲這實際上是一個相對普遍的問題?我完全不知道這裏發生了什麼?提前致謝!

+0

您是否在清單中使用了'android:process'屬性? – CommonsWare

+0

我其實沒有編寫代碼,但似乎android:process被用於我的後臺服務。這聽起來像是它的罪魁禍首,但現在我有點擔心關閉它。是否有充分的理由讓該服務以不同於應用程序其他部分的方式運行? – akhalsa

+0

另外,我真的很感謝你的幫助,如果你發佈這個答案,我會將其標記爲正確的。 – akhalsa

回答

2

它似乎機器人:用於我的後臺服務

這就是這個特定困難的常見原因的過程。從Java源代碼的角度來看,它只是一個應用程序,但是您運行兩個獨立進程的事實意味着您有兩個單獨的對象堆,因此一個堆中的全局(靜態數據成員)將與同一個堆不同,在另一個堆中命名爲global。

是否有充分的理由讓服務運行在與應用程序其餘部分不同的進程中?

通常不會。正如你所看到的,它會導致你的應用消耗更多的內存和更多的CPU時間,並限制各種組件(運行在不同進程中)互操作的能力。我通常會針對多個進程提出建議。這就是說,改變它將保證徹底的測試,特別是如果你不知道爲什麼使用這種技術的原因。