Android同步不工作

Android同步不工作,android,multithreading,concurrency,Android,Multithreading,Concurrency,在我的一个Android应用程序中,我使用一个singleton类来管理InApp账单。在这个类中,我使用一个接口列表来通知来自InApp计费服务器的响应 由于我的应用程序是多线程的,我希望同步此列表,因此我已完成以下操作: public class InAppPurchasesManager { ... private List<InAppPurchasesInterface> requestProductsListeners; ... public

在我的一个Android应用程序中,我使用一个singleton类来管理InApp账单。在这个类中,我使用一个接口列表来通知来自InApp计费服务器的响应

由于我的应用程序是多线程的,我希望同步此列表,因此我已完成以下操作:

public class InAppPurchasesManager {
    ...
    private List<InAppPurchasesInterface> requestProductsListeners;
    ...
    public static InAppPurchasesManager getInstance() {

        if (mInstance == null) {
            mInstance = new InAppPurchasesManager();
        }
        return mInstance;
    }

    private InAppPurchasesManager() {}

    public void initInAppPurchasesManager(Application app) {
        ctxt = app.getApplicationContext();
        mInstance.requestProductsListeners = Collections.synchronizedList(new ArrayList());
    }
    ...
    public void addRequestProductListener(InAppPurchasesInterface listener)
    {
        synchronized(requestProductsListeners)
        {
            if(!requestProductsListeners.contains(listener))
                requestProductsListeners.add(listener);
        }
    }

    public void removeRequestProductListener(InAppPurchasesInterface listener)
    {
        synchronized(requestProductsListeners)
        {
            requestProductsListeners.remove(listener);
        }
    }

    private void responseOnRequestProductsAndPurchase(boolean success)
    {
        callingIabHelper = false;
        synchronized(requestProductsListeners)
        {
            for(InAppPurchasesInterface listener : requestProductsListeners)
                listener.onRequestProductsAndPurchased(success);
            return;
        }
    }
    ...
    public interface InAppPurchasesInterface {

        void onServiceStarted(boolean success);
        void onRequestProductsAndPurchased(boolean success);
        void onRequestProductPurchased(Purchase purchase, int error);

    }

}
由于我不是同步和多线程方面的专家,我肯定我做错了什么。这些问题的任何解决方案都有效吗

也许在使用RequestProductsListener的方法的定义中添加“synchronized”

编辑: 我最后添加了synchronized,但由于“java.util.ConcurrentModificationException”而导致的崩溃不断出现

这是我现在的代码:

public class InAppPurchasesManager {
    ...
    private List<InAppPurchasesInterface> requestProductsListeners;
    ...
    public static InAppPurchasesManager getInstance() {

        if (mInstance == null) {
            mInstance = new InAppPurchasesManager();
        }
        return mInstance;
    }

    private InAppPurchasesManager() {}

    public void initInAppPurchasesManager(Application app) {
        ctxt = app.getApplicationContext();
        mInstance.requestProductsListeners = Collections.synchronizedList(new ArrayList());
    }
    ...
    public synchronized void addRequestProductListener(InAppPurchasesInterface listener)
    {
        synchronized(requestProductsListeners)
        {
            if(!requestProductsListeners.contains(listener))
                requestProductsListeners.add(listener);
        }
    }

    public synchronized void removeRequestProductListener(InAppPurchasesInterface listener)
    {
        synchronized(requestProductsListeners)
        {
            requestProductsListeners.remove(listener);
        }
    }

    private synchronized void responseOnRequestProductsAndPurchase(boolean success)
    {
        callingIabHelper = false;
        synchronized(requestProductsListeners)
        {
            for(InAppPurchasesInterface listener : requestProductsListeners)
                listener.onRequestProductsAndPurchased(success);
            return;
        }
    }
    ...
    public interface InAppPurchasesInterface {

        void onServiceStarted(boolean success);
        void onRequestProductsAndPurchased(boolean success);
        void onRequestProductPurchased(Purchase purchase, int error);

    }

}

ConcurrentModificationException
不一定会发生,因为违反了线程安全性。当您迭代一个集合并尝试同时修改它(添加/删除项)时,就会发生这种情况。检查类中是否有这样的代码。然后我完全错了,因为我认为同步块实际上避免了同时访问同一代码或变量。因此,如果一个线程执行并添加,而另一个线程在同一个数组中执行迭代,我应该如何做才能避免ConcurrentModificationException?它只能有一个线程:您可能有一个for循环,在其中调用Add、remove或任何其他更改项目数的操作。你有这样的代码吗?我需要更多的细节:调用
initInAppPurchasesManager()
requestProductsListeners
的所有用法。我再次编辑这个问题。关于“requestProductsListeners的所有用法”,它只在我的问题中描述的类中使用,其他地方没有调用它。
public class InAppPurchasesManager {
    ...
    private List<InAppPurchasesInterface> requestProductsListeners;
    ...
    public static InAppPurchasesManager getInstance() {

        if (mInstance == null) {
            mInstance = new InAppPurchasesManager();
        }
        return mInstance;
    }

    private InAppPurchasesManager() {}

    public void initInAppPurchasesManager(Application app) {
        ctxt = app.getApplicationContext();
        mInstance.requestProductsListeners = Collections.synchronizedList(new ArrayList());
    }
    ...
    public synchronized void addRequestProductListener(InAppPurchasesInterface listener)
    {
        synchronized(requestProductsListeners)
        {
            if(!requestProductsListeners.contains(listener))
                requestProductsListeners.add(listener);
        }
    }

    public synchronized void removeRequestProductListener(InAppPurchasesInterface listener)
    {
        synchronized(requestProductsListeners)
        {
            requestProductsListeners.remove(listener);
        }
    }

    private synchronized void responseOnRequestProductsAndPurchase(boolean success)
    {
        callingIabHelper = false;
        synchronized(requestProductsListeners)
        {
            for(InAppPurchasesInterface listener : requestProductsListeners)
                listener.onRequestProductsAndPurchased(success);
            return;
        }
    }
    ...
    public interface InAppPurchasesInterface {

        void onServiceStarted(boolean success);
        void onRequestProductsAndPurchased(boolean success);
        void onRequestProductPurchased(Purchase purchase, int error);

    }

}
public class MyApp extends MultiDexApplication {
@Override
public void onCreate() {
    super.onCreate();
     InAppPurchasesManager.getInstance().initInAppPurchasesManager(this);
}