我希望有人可以为我清除我的代码中发生的事情。我有一段代码读取和写入我的数据库,它既从服务运行,也从我的活动运行。无论是从服务还是活动调用,我都需要这段代码是线程安全的。因此,我采用了代码块所在的类,并制作了一个静态锁定对象以使其保持线程安全,如下面的代码块所示:
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 的日志。日志告诉我,不知何故,我似乎有 2 个不同的 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 服务使用与主进程不同的类加载器?有解决方法吗?我认为这实际上是一个相对普遍的问题?我完全偏离了这里发生的事情吗?提前致谢!