Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/196.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android静态变量在服务中与在活动中不同_Android_Multithreading_Android Service_Classloader - Fatal编程技术网

Android静态变量在服务中与在活动中不同

Android静态变量在服务中与在活动中不同,android,multithreading,android-service,classloader,Android,Multithreading,Android Service,Classloader,我希望有人能帮我弄清楚我的代码里发生了什么。我有一个代码块读写到我的数据库,它是从服务和我的活动中运行的。我需要这段代码是线程安全的,不管它是从服务还是从活动中调用的。因此,我采用了代码块所在的类,并创建了一个静态锁定对象,以保持其线程安全,正如您在下面的代码块中所看到的: synchronized(AnalyticsMessages.sync_lock){ Log.v("mixpanel", "locking off of: "+AnalyticsMessage

我希望有人能帮我弄清楚我的代码里发生了什么。我有一个代码块读写到我的数据库,它是从服务和我的活动中运行的。我需要这段代码是线程安全的,不管它是从服务还是从活动中调用的。因此,我采用了代码块所在的类,并创建了一个静态锁定对象,以保持其线程安全,正如您在下面的代码块中所看到的:

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在分析消息中定义如下:

private static final Object sync_lock = new Object();
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;
    }
}
很明显,它没有正确锁定,因此日志带有toString。日志告诉我,我似乎有两个不同的sync_lock变量(因为它在内存中打印地址)。我应该提到,AnalyticsMessages是这样实例化的:

private static final Object sync_lock = new Object();
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服务使用与主进程不同的类加载器?有解决办法吗?我认为这实际上是一个比较普遍的问题?我是不是完全偏离了轨道?提前谢谢

我的后台服务似乎使用了android:process

这是造成这种特殊困难的一个常见原因。虽然,从Java源代码的角度来看,这都是一个应用程序,但您运行两个单独的进程这一事实意味着您有两个单独的对象堆,因此一个堆中的全局(静态数据成员)将不同于另一个堆中相同的命名全局

是否有充分的理由让服务运行在与应用程序其余部分不同的进程中


通常不会。正如您所看到的,它会导致应用程序消耗更多内存和CPU时间,并限制各种组件(在不同进程中运行)的互操作能力。我通常反对多个过程。话虽如此,更改它将需要进行彻底的测试,特别是如果您不知道为什么要首先使用该技术。

您是否在清单中使用了
android:process
属性?实际上,我没有编写代码,但似乎android:process用于我的后台服务。这听起来像是罪魁祸首,但现在我有点担心关掉它。是否有充分的理由让服务在不同于应用程序其余部分的进程中运行?此外,我非常感谢您的帮助,如果您将此作为答案发布,我会将其标记为正确。可能服务是在应用程序之外的单独进程中运行的,因为当用户从最近的应用程序关闭应用程序时,它不应该被杀死?