Skip to content

Commit

Permalink
Disable search for ScheduledExecutorService.setRemoveOnCancelPolicy()…
Browse files Browse the repository at this point in the history
… on Android API < 21
  • Loading branch information
artem-zinnatullin committed Jul 29, 2015
1 parent 3494c00 commit 85d2e83
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 29 deletions.
14 changes: 13 additions & 1 deletion src/main/java/rx/internal/schedulers/NewThreadWorker.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,25 @@ public class NewThreadWorker extends Scheduler.Worker implements Subscription {
private static final boolean PURGE_FORCE;
/** The purge frequency in milliseconds. */
public static final int PURGE_FREQUENCY;
private static final boolean IS_ANDROID;
/** Android supports setRemoveOnCancelPolicy since Android API 21 */
private static final boolean IS_ANDROID_AND_SUPPORTS_SET_REMOVE_ON_CANCEL_POLICY;
private static final ConcurrentHashMap<ScheduledThreadPoolExecutor, ScheduledThreadPoolExecutor> EXECUTORS;
private static final AtomicReference<ScheduledExecutorService> PURGE;
static {
EXECUTORS = new ConcurrentHashMap<ScheduledThreadPoolExecutor, ScheduledThreadPoolExecutor>();
PURGE = new AtomicReference<ScheduledExecutorService>();
PURGE_FORCE = Boolean.getBoolean(PURGE_FORCE_KEY);
PURGE_FREQUENCY = Integer.getInteger(FREQUENCY_KEY, 1000);

// Cached to prevent method call
IS_ANDROID = PlatformDependent.isAndroid();

final Integer androidApiVersion = PlatformDependent.getAndroidApiVersion();

// According to http://developer.android.com/reference/java/util/concurrent/ScheduledThreadPoolExecutor.html#setRemoveOnCancelPolicy(boolean)
// setRemoveOnCancelPolicy available since Android API 21
IS_ANDROID_AND_SUPPORTS_SET_REMOVE_ON_CANCEL_POLICY = androidApiVersion != null && androidApiVersion >= 21;
}
/**
* Registers the given executor service and starts the purge thread if not already started.
Expand Down Expand Up @@ -112,7 +124,7 @@ static void purgeExecutors() {
* @return true if the policy was successfully enabled
*/
public static boolean tryEnableCancelPolicy(ScheduledExecutorService exec) {
if (!PURGE_FORCE) {
if (!PURGE_FORCE && (!IS_ANDROID || IS_ANDROID_AND_SUPPORTS_SET_REMOVE_ON_CANCEL_POLICY)) {
for (Method m : exec.getClass().getMethods()) {
if (m.getName().equals("setRemoveOnCancelPolicy")
&& m.getParameterTypes().length == 1
Expand Down
55 changes: 27 additions & 28 deletions src/main/java/rx/internal/util/PlatformDependent.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,51 +15,50 @@
*/
package rx.internal.util;

import java.security.AccessController;
import java.security.PrivilegedAction;

/**
* Allow platform dependent logic such as checks for Android.
*
*
* Modeled after Netty with some code copy/pasted from: https://github.com/netty/netty/blob/master/common/src/main/java/io/netty/util/internal/PlatformDependent.java
*/
public final class PlatformDependent {

private static final boolean IS_ANDROID = isAndroid0();
// Will be null if current platform is not Android
// Or if Android API Version can not be resolved.
private static final Integer ANDROID_API_VERSION = resolveAndroidApiVersion();

private static final boolean IS_ANDROID = ANDROID_API_VERSION != null;

/**
* Returns {@code true} if and only if the current platform is Android
* Returns {@code true} if and only if the current platform is Android.
*/
public static boolean isAndroid() {
return IS_ANDROID;
}

private static boolean isAndroid0() {
boolean android;
try {
Class.forName("android.app.Application", false, getSystemClassLoader());
android = true;
} catch (Exception e) {
// Failed to load the class uniquely available in Android.
android = false;
}

return android;
/**
* Returns version of Android API.
*
* @return version of Android API or {@code null} if version can not be resolved or current platform is not Android.
*/
public static Integer getAndroidApiVersion() {
return ANDROID_API_VERSION;
}

/**
* Return the system {@link ClassLoader}.
* Resolves version of Android API.
*
* @return version of Android API or {@code null} if version can not be resolved.
* @see <a href="http://developer.android.com/reference/android/os/Build.VERSION.html#SDK_INT">Documentation</a>
*/
static ClassLoader getSystemClassLoader() {
if (System.getSecurityManager() == null) {
return ClassLoader.getSystemClassLoader();
} else {
return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
@Override
public ClassLoader run() {
return ClassLoader.getSystemClassLoader();
}
});
private static Integer resolveAndroidApiVersion() {
try {
return (Integer) Class
.forName("android.os.Build$VERSION")
.getField("SDK_INT")
.get(null);
} catch (Exception e) {
// Can not resolve version of Android API :(
return null;
}
}
}

0 comments on commit 85d2e83

Please sign in to comment.