未验证 提交 49aa9fe9 编写于 作者: J Jake Wharton 提交者: GitHub

Merge pull request #3344 from square/jakew/get-a-handle/2020-03-24

Don't attempt to resolve Lookup ctor on API 24/25
......@@ -61,6 +61,9 @@ class Platform {
// that ignores the visibility of the declaringClass.
lookupConstructor = Lookup.class.getDeclaredConstructor(Class.class, int.class);
lookupConstructor.setAccessible(true);
} catch (NoClassDefFoundError ignored) {
// Android API 24 or 25 where Lookup doesn't exist. Calling default methods on non-public
// interfaces will fail, but there's nothing we can do about it.
} catch (NoSuchMethodException ignored) {
// Assume JDK 14+ which contains a fix that allows a regular lookup to succeed.
// See https://bugs.openjdk.java.net/browse/JDK-8209005.
......@@ -119,7 +122,16 @@ class Platform {
return new MainThreadExecutor();
}
static class MainThreadExecutor implements Executor {
@Nullable @Override Object invokeDefaultMethod(Method method, Class<?> declaringClass,
Object object, @Nullable Object... args) throws Throwable {
if (Build.VERSION.SDK_INT < 26) {
throw new UnsupportedOperationException(
"Calling default methods on API 24 and 25 is not supported");
}
return super.invokeDefaultMethod(method, declaringClass, object, args);
}
static final class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
......
/*
* Copyright (C) 2016 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package retrofit2;
import java.io.IOException;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import retrofit2.helpers.ToStringConverterFactory;
import retrofit2.http.GET;
import retrofit2.http.Query;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import static org.robolectric.annotation.Config.NEWEST_SDK;
import static org.robolectric.annotation.Config.NONE;
@RunWith(RobolectricTestRunner.class)
@Config(sdk = NEWEST_SDK, manifest = NONE)
public final class DefaultMethodsAndroidTest {
@Rule public final MockWebServer server = new MockWebServer();
interface Example {
@GET("/") Call<String> user(@Query("name") String name);
default Call<String> user() {
return user("hey");
}
}
@Config(sdk = 24)
@Test public void failsOnApi24() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(server.url("/"))
.addConverterFactory(new ToStringConverterFactory())
.build();
Example example = retrofit.create(Example.class);
try {
example.user();
fail();
} catch (UnsupportedOperationException e) {
assertThat(e).hasMessage("Calling default methods on API 24 and 25 is not supported");
}
}
@Config(sdk = 25)
@Test public void failsOnApi25() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(server.url("/"))
.addConverterFactory(new ToStringConverterFactory())
.build();
Example example = retrofit.create(Example.class);
try {
example.user();
fail();
} catch (UnsupportedOperationException e) {
assertThat(e).hasMessage("Calling default methods on API 24 and 25 is not supported");
}
}
/**
* Notably, this does not test that it works correctly on API 26+. Merely that the special casing
* of API 24/25 does not trigger.
*/
@Test public void doesNotFailOnApi26() throws IOException {
server.enqueue(new MockResponse().setBody("Hi"));
server.enqueue(new MockResponse().setBody("Hi"));
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(server.url("/"))
.addConverterFactory(new ToStringConverterFactory())
.build();
Example example = retrofit.create(Example.class);
Response<String> response = example.user().execute();
assertThat(response.body()).isEqualTo("Hi");
Response<String> response2 = example.user("Hi").execute();
assertThat(response2.body()).isEqualTo("Hi");
}
}
......@@ -26,7 +26,7 @@ import retrofit2.http.Query;
import static org.assertj.core.api.Assertions.assertThat;
public final class Java8DefaultMethodsTest {
public final class DefaultMethodsTest {
@Rule public final MockWebServer server = new MockWebServer();
interface Example {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册