在我的一个Android应用中,我使用单例类来管理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);
}
}
但由于并发访问requestProductListeners,我仍然收到很多崩溃。
这是一个崩溃样本:
Fatal Exception: java.util.ConcurrentModificationException
at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
at com.mypackage.managers.InAppPurchasesManager.responseOnRequestProductsAndPurchase(InAppPurchasesManager.java:173)
at com.mypackage.managers.InAppPurchasesManager.access$100(InAppPurchasesManager.java:24)
at com.mypackage.managers.InAppPurchasesManager$2.onQueryInventoryFinished(InAppPurchasesManager.java:145)
at com.mypackage.auxiliary.inappbilling.IabHelper$2$1.run(IabHelper.java:741)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7329)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
由于我不是同步和多线程的专家,我确定我做错了什么。这些问题的任何解决方案是否有效? https://stackoverflow.com/a/2120409
也许添加&#34;同步&#34;到使用requestProductsListeners的方法的定义?
编辑: 我终于添加了同步但崩溃的原因是&#34; java.util.ConcurrentModificationException&#34;继续出现。
这是我现在的代码:
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);
}
}
我错过了什么?
编辑2:
要回答Maxim Blumental的评论,我添加以下信息:
addRequestProductListener方法(在数组中添加一个监听器)在OnResume()方法中调用一些需要产品及其价格的片段。
一旦Google发送了有关产品及其价格的信息,就会调用responseOnRequestProductsAndPurchase方法(遍历调用回调的侦听器数组)。
一旦刚刚提到的回调结束,就会调用removeRequestProductListener方法(从数组中删除监听器)。
仅在
中调用initInAppPurchasesManagerpublic class MyApp extends MultiDexApplication {
@Override
public void onCreate() {
super.onCreate();
InAppPurchasesManager.getInstance().initInAppPurchasesManager(this);
}