Execute async IAB methods on single named thread

pull/413/head
Alex Baker 10 years ago
parent 2f3c0f9430
commit 45fe86d46f

@ -43,9 +43,13 @@ public class Tracker {
analytics.setAppOptOut(!enabled); analytics.setAppOptOut(!enabled);
} }
public void reportException(Exception e) { public void reportException(Throwable t) {
reportException(Thread.currentThread(), t);
}
public void reportException(Thread thread, Throwable t) {
tracker.send(new HitBuilders.ExceptionBuilder() tracker.send(new HitBuilders.ExceptionBuilder()
.setDescription(exceptionParser.getDescription(Thread.currentThread().getName(), e)) .setDescription(exceptionParser.getDescription(thread.getName(), t))
.setFatal(false) .setFatal(false)
.build()); .build());
} }

@ -17,7 +17,11 @@ public class Tracker {
} }
public void reportException(Exception e) { public void reportException(Throwable t) {
}
public void reportException(Thread thread, Throwable t) {
} }

@ -36,6 +36,7 @@ import org.json.JSONException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.Executor;
/** /**
@ -69,6 +70,9 @@ import java.util.List;
* *
*/ */
public class IabHelper { public class IabHelper {
private final Executor executor;
// Is debug logging enabled? // Is debug logging enabled?
boolean mDebugLog = false; boolean mDebugLog = false;
String mDebugTag = "IabHelper"; String mDebugTag = "IabHelper";
@ -164,9 +168,10 @@ public class IabHelper {
* public key in your application's page on Google Play Developer Console. Note that this * public key in your application's page on Google Play Developer Console. Note that this
* is NOT your "developer public key". * is NOT your "developer public key".
*/ */
public IabHelper(Context ctx, String base64PublicKey) { public IabHelper(Context ctx, String base64PublicKey, Executor executor) {
mContext = ctx.getApplicationContext(); mContext = ctx.getApplicationContext();
mSignatureBase64 = base64PublicKey; mSignatureBase64 = base64PublicKey;
this.executor = executor;
logDebug("IAB helper created."); logDebug("IAB helper created.");
} }
@ -649,7 +654,7 @@ public class IabHelper {
checkNotDisposed(); checkNotDisposed();
checkSetupDone("queryInventory"); checkSetupDone("queryInventory");
flagStartAsync("refresh inventory"); flagStartAsync("refresh inventory");
(new Thread(new Runnable() { executor.execute(new Runnable() {
public void run() { public void run() {
IabResult result = new IabResult(BILLING_RESPONSE_RESULT_OK, "Inventory refresh successful."); IabResult result = new IabResult(BILLING_RESPONSE_RESULT_OK, "Inventory refresh successful.");
Inventory inv = null; Inventory inv = null;
@ -672,7 +677,7 @@ public class IabHelper {
}); });
} }
} }
})).start(); });
} }
public void queryInventoryAsync(QueryInventoryFinishedListener listener) { public void queryInventoryAsync(QueryInventoryFinishedListener listener) {
@ -1006,7 +1011,7 @@ public class IabHelper {
final OnConsumeMultiFinishedListener multiListener) { final OnConsumeMultiFinishedListener multiListener) {
final Handler handler = new Handler(); final Handler handler = new Handler();
flagStartAsync("consume"); flagStartAsync("consume");
(new Thread(new Runnable() { executor.execute(new Runnable() {
public void run() { public void run() {
final List<IabResult> results = new ArrayList<IabResult>(); final List<IabResult> results = new ArrayList<IabResult>();
for (Purchase purchase : purchases) { for (Purchase purchase : purchases) {
@ -1035,7 +1040,7 @@ public class IabHelper {
}); });
} }
} }
})).start(); });
} }
void logDebug(String msg) { void logDebug(String msg) {

@ -44,9 +44,13 @@ public class Tracker {
analytics.setAppOptOut(!enabled); analytics.setAppOptOut(!enabled);
} }
public void reportException(Exception e) { public void reportException(Throwable t) {
reportException(Thread.currentThread(), t);
}
public void reportException(Thread thread, Throwable t) {
tracker.send(new HitBuilders.ExceptionBuilder() tracker.send(new HitBuilders.ExceptionBuilder()
.setDescription(exceptionParser.getDescription(Thread.currentThread().getName(), e)) .setDescription(exceptionParser.getDescription(thread.getName(), t))
.setFatal(false) .setFatal(false)
.build()); .build());
} }

@ -14,7 +14,10 @@ import org.tasks.R;
import org.tasks.injection.ForApplication; import org.tasks.injection.ForApplication;
import org.tasks.preferences.Preferences; import org.tasks.preferences.Preferences;
import java.util.concurrent.Executor;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import timber.log.Timber; import timber.log.Timber;
@ -25,14 +28,17 @@ public class InventoryHelper implements IabBroadcastReceiver.IabBroadcastListene
private final Context context; private final Context context;
private final Preferences preferences; private final Preferences preferences;
private final Broadcaster broadcaster; private final Broadcaster broadcaster;
private final Executor executor;
private Inventory inventory; private Inventory inventory;
@Inject @Inject
public InventoryHelper(@ForApplication Context context, Preferences preferences, Broadcaster broadcaster) { public InventoryHelper(@ForApplication Context context, Preferences preferences,
Broadcaster broadcaster, @Named("iab-executor") Executor executor) {
this.context = context; this.context = context;
this.preferences = preferences; this.preferences = preferences;
this.broadcaster = broadcaster; this.broadcaster = broadcaster;
this.executor = executor;
} }
public void initialize() { public void initialize() {
@ -41,7 +47,7 @@ public class InventoryHelper implements IabBroadcastReceiver.IabBroadcastListene
} }
public void refreshInventory() { public void refreshInventory() {
final IabHelper helper = new IabHelper(context, context.getString(R.string.gp_key)); final IabHelper helper = new IabHelper(context, context.getString(R.string.gp_key), executor);
helper.startSetup(getSetupListener(helper)); helper.startSetup(getSetupListener(helper));
} }

@ -21,8 +21,10 @@ import org.tasks.preferences.Preferences;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.Executor;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import timber.log.Timber; import timber.log.Timber;
@ -37,18 +39,20 @@ public class PurchaseHelper implements IabHelper.OnIabSetupFinishedListener {
private final Tracker tracker; private final Tracker tracker;
private final Broadcaster broadcaster; private final Broadcaster broadcaster;
private final InventoryHelper inventory; private final InventoryHelper inventory;
private Executor executor;
private PurchaseHelperCallback activityResultCallback; private PurchaseHelperCallback activityResultCallback;
private IabHelper iabHelper; private IabHelper iabHelper;
@Inject @Inject
public PurchaseHelper(@ForApplication Context context, Preferences preferences, Tracker tracker, public PurchaseHelper(@ForApplication Context context, Preferences preferences, Tracker tracker,
Broadcaster broadcaster, InventoryHelper inventory) { Broadcaster broadcaster, InventoryHelper inventory, @Named("iab-executor") Executor executor) {
this.context = context; this.context = context;
this.preferences = preferences; this.preferences = preferences;
this.tracker = tracker; this.tracker = tracker;
this.broadcaster = broadcaster; this.broadcaster = broadcaster;
this.inventory = inventory; this.inventory = inventory;
this.executor = executor;
} }
@Override @Override
@ -101,7 +105,7 @@ public class PurchaseHelper implements IabHelper.OnIabSetupFinishedListener {
if (themes != null) { if (themes != null) {
purchases.add(themes); purchases.add(themes);
} }
final IabHelper iabHelper = new IabHelper(context, context.getString(R.string.gp_key)); final IabHelper iabHelper = new IabHelper(context, context.getString(R.string.gp_key), executor);
iabHelper.enableDebugLogging(true); iabHelper.enableDebugLogging(true);
iabHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() { iabHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
@Override @Override
@ -150,7 +154,7 @@ public class PurchaseHelper implements IabHelper.OnIabSetupFinishedListener {
callback.purchaseCompleted(false, sku); callback.purchaseCompleted(false, sku);
return; return;
} }
iabHelper = new IabHelper(context, context.getString(R.string.gp_key)); iabHelper = new IabHelper(context, context.getString(R.string.gp_key), executor);
iabHelper.enableDebugLogging(BuildConfig.DEBUG); iabHelper.enableDebugLogging(BuildConfig.DEBUG);
Timber.d("%s: startSetup", iabHelper); Timber.d("%s: startSetup", iabHelper);
iabHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() { iabHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {

@ -0,0 +1,38 @@
package org.tasks;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.tasks.analytics.Tracker;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
public class ErrorReportingSingleThreadExecutor implements Executor, Thread.UncaughtExceptionHandler {
private final ExecutorService executorService;
private final Tracker tracker;
public ErrorReportingSingleThreadExecutor(String nameFormat, Tracker tracker) {
executorService = newSingleThreadExecutor(
new ThreadFactoryBuilder()
.setNameFormat(String.format("%s-%%d", nameFormat))
.setUncaughtExceptionHandler(this)
.build());
this.tracker = tracker;
}
@Override
public void execute(Runnable runnable) {
try {
executorService.execute(runnable);
} catch (Exception e) {
tracker.reportException(e);
}
}
@Override
public void uncaughtException(Thread thread, Throwable throwable) {
tracker.reportException(thread, throwable);
}
}

@ -2,6 +2,14 @@ package org.tasks.injection;
import android.content.Context; import android.content.Context;
import org.tasks.ErrorReportingSingleThreadExecutor;
import org.tasks.analytics.Tracker;
import java.util.concurrent.Executor;
import javax.inject.Named;
import javax.inject.Singleton;
import dagger.Module; import dagger.Module;
import dagger.Provides; import dagger.Provides;
@ -18,4 +26,11 @@ public class ApplicationModule {
public Context getApplicationContext() { public Context getApplicationContext() {
return context; return context;
} }
@Provides
@Singleton
@Named("iab-executor")
public Executor getIabExecutor(Tracker tracker) {
return new ErrorReportingSingleThreadExecutor("iab-executor", tracker);
}
} }

Loading…
Cancel
Save