From 2f5adfc3be135447b40c256e1690f7c277f035da Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Sun, 15 Sep 2013 20:24:46 +0200 Subject: [PATCH] Allow WalletAppKit to have a non blocking startup. --- .../com/google/bitcoin/kits/WalletAppKit.java | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/google/bitcoin/kits/WalletAppKit.java b/core/src/main/java/com/google/bitcoin/kits/WalletAppKit.java index a505b529..c972aa85 100644 --- a/core/src/main/java/com/google/bitcoin/kits/WalletAppKit.java +++ b/core/src/main/java/com/google/bitcoin/kits/WalletAppKit.java @@ -37,9 +37,20 @@ import static com.google.common.base.Preconditions.checkState; /** *

Utility class that wraps the boilerplate needed to set up a new SPV bitcoinj app. Instantiate it with a directory * and file prefix, optionally configure a few things, then use start or startAndWait. The object will construct and - * configure a {@link BlockChain}, {@link SPVBlockStore}, {@link Wallet} and {@link PeerGroup}. Startup will be - * considered complete once the block chain has fully synchronized, so it can take a while. Once complete, you can - * go ahead and add the listeners you need to the underlying objects.

+ * configure a {@link BlockChain}, {@link SPVBlockStore}, {@link Wallet} and {@link PeerGroup}. Depending on the value + * of the blockingStartup property, startup will be considered complete once the block chain has fully synchronized, + * so it can take a while.

+ * + *

To add listeners and modify the objects that are constructed, you can either do that by overriding the + * {@link #onSetupCompleted()} method (which will run on a background thread) and make your changes there, + * or by waiting for the service to start and then accessing the objects from wherever you want. However, you cannot + * access the objects this class creates until startup is complete.

+ * + *

The asynchronous design of this class may seem puzzling (just use {@link #startAndWait()} if you don't want that). + * It is to make it easier to fit bitcoinj into GUI apps, which require a high degree of responsiveness on their main + * thread which handles all the animation and user interaction. Even when blockingStart is false, initializing bitcoinj + * means doing potentially blocking file IO, generating keys and other potentially intensive operations. By running it + * on a background thread, there's no risk of accidentally causing UI lag.

* *

Note that {@link #startAndWait()} can throw an unchecked {@link com.google.common.util.concurrent.UncheckedExecutionException} * if anything goes wrong during startup - you should probably handle it and use {@link Exception#getCause()} to figure @@ -61,6 +72,7 @@ public class WalletAppKit extends AbstractIdleService { private PeerEventListener downloadListener; private boolean autoStop = true; private InputStream checkpoints; + private boolean blockingStartup = true; public WalletAppKit(NetworkParameters params, File directory, String filePrefix) { this.params = checkNotNull(params); @@ -117,6 +129,17 @@ public class WalletAppKit extends AbstractIdleService { return this; } + /** + * If true (the default) then the startup of this service won't be considered complete until the network has been + * brought up, peer connections established and the block chain synchronised. Therefore {@link #startAndWait()} can + * potentially take a very long time. If false, then startup is considered complete once the network activity + * begins and peer connections/block chain sync will continue in the background. + */ + public WalletAppKit setBlockingStartup(boolean blockingStartup) { + this.blockingStartup = blockingStartup; + return this; + } + /** *

Override this to load all wallet extensions if any are necessary.

*