Skip to content

Commit 7fd136a

Browse files
author
Roger Hu
committed
Add bolts tasks to this library
1 parent 2d92432 commit 7fd136a

18 files changed

+3481
-2
lines changed

bolts-tasks/build.gradle

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright (c) Facebook, Inc. and its affiliates.
2+
//
3+
// This source code is licensed under the MIT license found in the/
4+
// LICENSE file in the root directory of this source tree.
5+
6+
apply plugin: 'java'
7+
8+
configurations {
9+
provided
10+
}
11+
12+
sourceSets {
13+
main {
14+
compileClasspath += configurations.provided
15+
}
16+
}
17+
18+
dependencies {
19+
provided 'com.google.android:android:4.1.1.4'
20+
testImplementation 'junit:junit:4.12'
21+
}
22+
23+
24+
javadoc.options.addStringOption('Xdoclint:none', '-quiet')
25+
26+
task sourcesJar(type: Jar) {
27+
classifier = 'sources'
28+
from sourceSets.main.allJava
29+
}
30+
31+
task javadocJar (type: Jar, dependsOn: javadoc) {
32+
classifier = 'javadoc'
33+
from javadoc.destinationDir
34+
}
35+
36+
artifacts {
37+
archives sourcesJar
38+
archives javadocJar
39+
}
40+
41+
//endregion
42+
43+
//region Code Coverage
44+
45+
apply plugin: 'jacoco'
46+
47+
jacoco {
48+
toolVersion = '0.7.1.201405082137'
49+
}
50+
51+
jacocoTestReport {
52+
group = "Reporting"
53+
description = "Generate Jacoco coverage reports after running tests."
54+
reports {
55+
xml.enabled true
56+
html.enabled true
57+
}
58+
}
59+
60+
//endregion
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
package bolts;
8+
9+
import java.io.PrintStream;
10+
import java.io.PrintWriter;
11+
import java.util.ArrayList;
12+
import java.util.Arrays;
13+
import java.util.Collections;
14+
import java.util.List;
15+
16+
/**
17+
* Aggregates multiple {@code Throwable}s that may be thrown in the process of a task's execution.
18+
*
19+
* @see Task#whenAll(java.util.Collection)
20+
*/
21+
public class AggregateException extends Exception {
22+
private static final long serialVersionUID = 1L;
23+
24+
private static final String DEFAULT_MESSAGE = "There were multiple errors.";
25+
26+
private List<Throwable> innerThrowables;
27+
28+
/**
29+
* Constructs a new {@code AggregateException} with the current stack trace, the specified detail
30+
* message and with references to the inner throwables that are the cause of this exception.
31+
*
32+
* @param detailMessage
33+
* The detail message for this exception.
34+
* @param innerThrowables
35+
* The exceptions that are the cause of the current exception.
36+
*/
37+
public AggregateException(String detailMessage, Throwable[] innerThrowables) {
38+
this(detailMessage, Arrays.asList(innerThrowables));
39+
}
40+
41+
42+
/**
43+
* Constructs a new {@code AggregateException} with the current stack trace, the specified detail
44+
* message and with references to the inner throwables that are the cause of this exception.
45+
*
46+
* @param detailMessage
47+
* The detail message for this exception.
48+
* @param innerThrowables
49+
* The exceptions that are the cause of the current exception.
50+
*/
51+
public AggregateException(String detailMessage, List<? extends Throwable> innerThrowables) {
52+
super(detailMessage,
53+
innerThrowables != null && innerThrowables.size() > 0 ? innerThrowables.get(0) : null);
54+
this.innerThrowables = Collections.unmodifiableList(innerThrowables);
55+
}
56+
57+
/**
58+
* Constructs a new {@code AggregateException} with the current stack trace and with references to
59+
* the inner throwables that are the cause of this exception.
60+
*
61+
* @param innerThrowables
62+
* The exceptions that are the cause of the current exception.
63+
*/
64+
public AggregateException(List<? extends Throwable> innerThrowables) {
65+
this(DEFAULT_MESSAGE, innerThrowables);
66+
}
67+
68+
/**
69+
* Returns a read-only {@link List} of the {@link Throwable} instances that caused the current
70+
* exception.
71+
*/
72+
public List<Throwable> getInnerThrowables() {
73+
return innerThrowables;
74+
}
75+
76+
@Override
77+
public void printStackTrace(PrintStream err) {
78+
super.printStackTrace(err);
79+
80+
int currentIndex = -1;
81+
for (Throwable throwable : innerThrowables) {
82+
err.append("\n");
83+
err.append(" Inner throwable #");
84+
err.append(Integer.toString(++currentIndex));
85+
err.append(": ");
86+
throwable.printStackTrace(err);
87+
err.append("\n");
88+
}
89+
}
90+
91+
@Override
92+
public void printStackTrace(PrintWriter err) {
93+
super.printStackTrace(err);
94+
95+
int currentIndex = -1;
96+
for (Throwable throwable : innerThrowables) {
97+
err.append("\n");
98+
err.append(" Inner throwable #");
99+
err.append(Integer.toString(++currentIndex));
100+
err.append(": ");
101+
throwable.printStackTrace(err);
102+
err.append("\n");
103+
}
104+
}
105+
106+
/**
107+
* @deprecated Please use {@link #getInnerThrowables()} instead.
108+
*/
109+
@Deprecated
110+
public List<Exception> getErrors() {
111+
List<Exception> errors = new ArrayList<Exception>();
112+
if (innerThrowables == null) {
113+
return errors;
114+
}
115+
116+
for (Throwable cause : innerThrowables) {
117+
if (cause instanceof Exception) {
118+
errors.add((Exception) cause);
119+
} else {
120+
errors.add(new Exception(cause));
121+
}
122+
}
123+
return errors;
124+
}
125+
126+
/**
127+
* @deprecated Please use {@link #getInnerThrowables()} instead.
128+
*/
129+
@Deprecated
130+
public Throwable[] getCauses() {
131+
return innerThrowables.toArray(new Throwable[innerThrowables.size()]);
132+
}
133+
134+
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/*
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
package bolts;
8+
9+
import android.annotation.SuppressLint;
10+
import android.os.Build;
11+
import android.os.Handler;
12+
import android.os.Looper;
13+
14+
import java.util.concurrent.Executor;
15+
import java.util.concurrent.ExecutorService;
16+
import java.util.concurrent.LinkedBlockingQueue;
17+
import java.util.concurrent.ThreadFactory;
18+
import java.util.concurrent.ThreadPoolExecutor;
19+
import java.util.concurrent.TimeUnit;
20+
21+
/**
22+
* This was created because the helper methods in {@link java.util.concurrent.Executors} do not work
23+
* as people would normally expect.
24+
*
25+
* Normally, you would think that a cached thread pool would create new threads when necessary,
26+
* queue them when the pool is full, and kill threads when they've been inactive for a certain
27+
* period of time. This is not how {@link java.util.concurrent.Executors#newCachedThreadPool()}
28+
* works.
29+
*
30+
* Instead, {@link java.util.concurrent.Executors#newCachedThreadPool()} executes all tasks on
31+
* a new or cached thread immediately because corePoolSize is 0, SynchronousQueue is a queue with
32+
* size 0 and maxPoolSize is Integer.MAX_VALUE. This is dangerous because it can create an unchecked
33+
* amount of threads.
34+
*/
35+
/* package */ final class AndroidExecutors {
36+
37+
private static final AndroidExecutors INSTANCE = new AndroidExecutors();
38+
39+
private final Executor uiThread;
40+
41+
private AndroidExecutors() {
42+
uiThread = new UIThreadExecutor();
43+
}
44+
45+
/**
46+
* Nexus 5: Quad-Core
47+
* Moto X: Dual-Core
48+
*
49+
* AsyncTask:
50+
* CORE_POOL_SIZE = CPU_COUNT + 1
51+
* MAX_POOL_SIZE = CPU_COUNT * 2 + 1
52+
*
53+
* https://github.com/android/platform_frameworks_base/commit/719c44e03b97e850a46136ba336d729f5fbd1f47
54+
*/
55+
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
56+
/* package */ static final int CORE_POOL_SIZE = CPU_COUNT + 1;
57+
/* package */ static final int MAX_POOL_SIZE = CPU_COUNT * 2 + 1;
58+
/* package */ static final long KEEP_ALIVE_TIME = 1L;
59+
60+
/**
61+
* Creates a proper Cached Thread Pool. Tasks will reuse cached threads if available
62+
* or create new threads until the core pool is full. tasks will then be queued. If an
63+
* task cannot be queued, a new thread will be created unless this would exceed max pool
64+
* size, then the task will be rejected. Threads will time out after 1 second.
65+
*
66+
* Core thread timeout is only available on android-9+.
67+
*
68+
* @return the newly created thread pool
69+
*/
70+
public static ExecutorService newCachedThreadPool() {
71+
ThreadPoolExecutor executor = new ThreadPoolExecutor(
72+
CORE_POOL_SIZE,
73+
MAX_POOL_SIZE,
74+
KEEP_ALIVE_TIME, TimeUnit.SECONDS,
75+
new LinkedBlockingQueue<Runnable>());
76+
77+
allowCoreThreadTimeout(executor, true);
78+
79+
return executor;
80+
}
81+
82+
/**
83+
* Creates a proper Cached Thread Pool. Tasks will reuse cached threads if available
84+
* or create new threads until the core pool is full. tasks will then be queued. If an
85+
* task cannot be queued, a new thread will be created unless this would exceed max pool
86+
* size, then the task will be rejected. Threads will time out after 1 second.
87+
*
88+
* Core thread timeout is only available on android-9+.
89+
*
90+
* @param threadFactory the factory to use when creating new threads
91+
* @return the newly created thread pool
92+
*/
93+
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
94+
ThreadPoolExecutor executor = new ThreadPoolExecutor(
95+
CORE_POOL_SIZE,
96+
MAX_POOL_SIZE,
97+
KEEP_ALIVE_TIME, TimeUnit.SECONDS,
98+
new LinkedBlockingQueue<Runnable>(),
99+
threadFactory);
100+
101+
allowCoreThreadTimeout(executor, true);
102+
103+
return executor;
104+
}
105+
106+
/**
107+
* Compatibility helper function for
108+
* {@link java.util.concurrent.ThreadPoolExecutor#allowCoreThreadTimeOut(boolean)}
109+
*
110+
* Only available on android-9+.
111+
*
112+
* @param executor the {@link java.util.concurrent.ThreadPoolExecutor}
113+
* @param value true if should time out, else false
114+
*/
115+
@SuppressLint("NewApi")
116+
public static void allowCoreThreadTimeout(ThreadPoolExecutor executor, boolean value) {
117+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
118+
executor.allowCoreThreadTimeOut(value);
119+
}
120+
}
121+
122+
/**
123+
* An {@link java.util.concurrent.Executor} that executes tasks on the UI thread.
124+
*/
125+
public static Executor uiThread() {
126+
return INSTANCE.uiThread;
127+
}
128+
129+
/**
130+
* An {@link java.util.concurrent.Executor} that runs tasks on the UI thread.
131+
*/
132+
private static class UIThreadExecutor implements Executor {
133+
@Override
134+
public void execute(Runnable command) {
135+
new Handler(Looper.getMainLooper()).post(command);
136+
}
137+
}
138+
}

0 commit comments

Comments
 (0)