18
18
import android .os .StrictMode ;
19
19
import androidx .annotation .RestrictTo ;
20
20
import java .util .ArrayList ;
21
+ import java .util .HashSet ;
21
22
import java .util .List ;
22
23
import java .util .ServiceLoader ;
24
+ import java .util .Set ;
23
25
24
26
/**
25
27
* Wrapper class for {@link ServiceLoader} that disables StrictMode.
@@ -86,7 +88,7 @@ public static <T> T loadSingleService(Class<T> serviceClass, Factory<T> defaultI
86
88
* @throws IllegalStateException if more than one service implementations are found
87
89
*/
88
90
public static <T > T loadSingleServiceOrNull (Class <T > serviceClass ) {
89
- List <T > impls = ServiceLoaderWrapper .loadService (serviceClass );
91
+ List <T > impls = filter ( ServiceLoaderWrapper .loadService (serviceClass ) );
90
92
if (impls .isEmpty ()) {
91
93
return null ;
92
94
} else if (impls .size () == 1 ) {
@@ -102,4 +104,27 @@ public static <T> T loadSingleServiceOrNull(Class<T> serviceClass) {
102
104
"Found more than one implementation for " + serviceClass .getName () + combinedImpls );
103
105
}
104
106
}
107
+
108
+ @ SuppressWarnings ("unchecked" )
109
+ private static <T > List <T > filter (List <T > services ) {
110
+ Set <Class <?>> superseded = new HashSet <>();
111
+ for (T service : services ) {
112
+ Class <? extends T > clazz = (Class <? extends T >) service .getClass ();
113
+ Supersedes supersedes = clazz .getAnnotation (Supersedes .class );
114
+ if (supersedes != null ) {
115
+ superseded .add (supersedes .value ());
116
+ }
117
+ }
118
+ if (superseded .isEmpty ()) {
119
+ return services ;
120
+ } else {
121
+ List <T > filtered = new ArrayList <>();
122
+ for (T service : services ) {
123
+ if (!superseded .contains (service .getClass ())) {
124
+ filtered .add (service );
125
+ }
126
+ }
127
+ return filtered ;
128
+ }
129
+ }
105
130
}
0 commit comments