有没有人玩过Retrofit 2.0,特别是Call.cancel()方法?
什么时候触发它的最佳时机?我曾试着打电话给它onStop()的Fragment,但遇到了与调用一些问题的时候,屏幕显示被关闭被取消.我也试着给它onDestroy()的Fragment,但是这种方法不会取消获得的触发呼叫ViewPager(例如标签之间的切换)
有没有人有这方面的实例?
我试图实现这个我的Loop repo:https: //github.com/lawloretienne/Loop
使用Retrofit 1,我们用来模拟Web服务并模拟网络延迟,如下所示:
MockRestAdapter mockRestAdapter = MockRestAdapter.from(restAdapter);
return mockRestAdapter.create(MyService.class, new MyServiceMock());
Run Code Online (Sandbox Code Playgroud)
MyService服务接口在哪里(将响应作为Rx Observables返回),并且MyServiceMock是实现此接口的类.
在Retrofit 2.0.0-beta3中,有一个全新的模拟系统(参见:https://github.com/square/retrofit/pull/1343)尚未记录.当我尝试类似的东西,我得到:
MockRetrofit mockRetrofit = new MockRetrofit.Builder(retrofit).build();
BehaviorDelegate<AuthService> delegate = mockRetrofit.create(MyService.class);
Run Code Online (Sandbox Code Playgroud)
我该如何转接电话MyServiceMock?
在问题的底部阅读编辑以寻找可能的替代解决方案,直到找到解决方案.
这是一个成功的帖子文件,其中包含两个使用POSTMan的参数.我试图通过改造来做同样的事但收到BadRequest.
邮差设置:
现在我在Android中如何做到这一点但失败了:
改造服务接口:
@Multipart
@POST("jobDocuments/upload")
Call<ResponseBody> upload(@Part("file") MultipartBody.Part file,@Part("folder") MultipartBody.Part folder,@Part("name") MultipartBody.Part name);
Run Code Online (Sandbox Code Playgroud)
这是我的@Background方法,用于生成上述服务来运行网络请求
CustDataClient service =
ServiceGenerator.createService(CustDataClient.class);
File file = new File(fileUri.getPath());
// create RequestBody instance from file
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part fileData =
MultipartBody.Part.createFormData("file", fileName, requestFile);
MultipartBody.Part folder =
MultipartBody.Part.createFormData("folder", "LeadDocuments");
MultipartBody.Part name =
MultipartBody.Part.createFormData("name", fileName);
// finally, execute the request
Call<ResponseBody> call = service.upload(fileData,folder,name);
try {
Response<ResponseBody> rr = call.execute();
ResponseBody empJobDocsResult = rr.body();//Bad Request here :(
Log.v("Upload", "success");
} catch …Run Code Online (Sandbox Code Playgroud) 我正在努力让一些罐头网络响应.我对实际请求有json响应,并且我有Retrofit接口来序列化响应.试图设置它我感到非常沮丧.我该怎么办?看来我的选择是,1)使用MockWebServer()2)使用RequestInterceptor().
在尝试使用1或2时,我不能在我的生活中实例化OkHttpClient()而不会失败,基本上这会把我试图立即死亡的每一件事.我得到一个java.lang.AssertionError,因为当OkHttpClient无法找到TLS算法时会抛出它.
if (builder.sslSocketFactory != null || !isTLS) {
this.sslSocketFactory = builder.sslSocketFactory;
} else {
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, null, null);
this.sslSocketFactory = sslContext.getSocketFactory();
} catch (GeneralSecurityException e) {
**throw new AssertionError(); // The system has no TLS. Just give up.**
}
}
Run Code Online (Sandbox Code Playgroud)
我试图使用unMock在android.jar中保留"javax.net.ssl"类,但这并没有解决错误.
unMock {
// URI to download the android-all.jar from. e.g. https://oss.sonatype.org/content/groups/public/org/robolectric/android-all/
downloadFrom 'https://oss.sonatype.org/content/groups/public/org/robolectric/android-all/4.3_r2-robolectric-0/android-all-4.3_r2-robolectric-0.jar'
keep "android.util.Log"
keep "javax.net.ssl"
}
Run Code Online (Sandbox Code Playgroud)
所以基本上,我已经遇到过如何通过改造2模拟网络请求的各种示例,但我无法克服这个障碍,而且我感觉很失败.我还没有看到其他人遇到过这个问题,而且我很困惑于每个人如何在所有测试中轻松实例化新的OkHttpClients.
以下是我正在使用的相关依赖项.
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-all:1.10.19'
testCompile 'org.powermock:powermock-mockito-release-full:1.6.4'
testCompile 'org.powermock:powermock-module-junit4:1.6.4'
testCompile 'org.easymock:easymock:3.4'
testCompile 'org.powermock:powermock-api-easymock:1.6.4'
testCompile …Run Code Online (Sandbox Code Playgroud) 我的Retrofit 2(2.0.2当前)客户端需要为请求添加自定义标头.
我正在使用an Interceptor将这些标头添加到所有请求中:
OkHttpClient httpClient = new OkHttpClient();
httpClient.networkInterceptors().add(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
final Request request = chain.request().newBuilder()
.addHeader("CUSTOM_HEADER_NAME_1", "CUSTOM_HEADER_VALUE_1")
.addHeader("CUSTOM_HEADER_NAME_2", "CUSTOM_HEADER_VALUE_2")
...
.addHeader("CUSTOM_HEADER_NAME_N", "CUSTOM_HEADER_VALUE_N")
.build();
return chain.proceed(request);
}
});
Retrofit retrofitClient = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(httpClient)
.build();
Run Code Online (Sandbox Code Playgroud)
我总是想添加一些标头,但是我只需要根据特定端点的要求添加一些标头,例如用户是否需要进行身份验证.
我希望能够在api级别控制它,例如使用注释,例如:
public interface MyApi {
@NO_AUTH
@POST("register")
Call<RegisterResponse> register(@Body RegisterRequest data);
@GET("user/{userId}")
Call<GetUserResponse> getUser(@Path("userId") String userId);
}
Run Code Online (Sandbox Code Playgroud)
发送请求时register无需添加身份验证令牌,但缺少@NO_AUTH注释的请求将具有令牌头.
根据我的理解,Retrofit 2不支持自定义注释,虽然我发现使用Retrofit 2的自定义注释的这种解决方法,但它看起来有点太多了.
我想避免每个请求传递这些标头的需要,例如:
public interface MyApi …Run Code Online (Sandbox Code Playgroud) 我正在使用改造2和OkHttp3从服务器请求数据.我刚刚添加了一个离线缓存代码,但它没有按预期工作.我收到错误"无法解析主机"<>":没有与主机名关联的地址."
当它试图从缓存中获取检索数据时(没有互联网连接时)会发生这种情况.下面是一段代码片段.
public static Interceptor provideCacheInterceptor() {
return new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
// re-write response header to force use of cache
CacheControl cacheControl = new CacheControl.Builder()
.maxAge(2, TimeUnit.MINUTES)
.build();
return response.newBuilder()
.header(CACHE_CONTROL, cacheControl.toString())
.build();
}
};
}
public static Interceptor provideOfflineCacheInterceptor() {
return new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (!hasNetwork) {
CacheControl cacheControl = new CacheControl.Builder()
.onlyIfCached()
.maxStale(7, TimeUnit.DAYS) …Run Code Online (Sandbox Code Playgroud) 有没有办法检测Retrofit响应是来自配置的OkHttp缓存还是实时响应?
客户定义:
Cache cache = new Cache(getCacheDirectory(context), 1024 * 1024 * 10);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.cache(cache)
.build();
Run Code Online (Sandbox Code Playgroud)
Api定义:
@GET("/object")
Observable<Result<SomeObject>> getSomeObject();
Run Code Online (Sandbox Code Playgroud)
示例电话:
RetroApi retroApi = new Retrofit.Builder()
.client(okHttpClient)
.baseUrl(baseUrl)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(RetroApi.class);
result = retroApi.getSomeObject().subscribe((Result<SomeObject> someObjectResult) -> {
isFromCache(someObjectResult); // ???
});
Run Code Online (Sandbox Code Playgroud) 当我们使用retrofit2与Rx进行API休息调用时,使用Single或Observable的最佳方法是什么?
public interface ApiService{
Single<Data> getDataFromServer();
Observable<Data> getDataFromServer();
}
Run Code Online (Sandbox Code Playgroud) 我正在使用Retrofit2和RxJava2CallAdapterFactory.
我使用的API总是将状态代码返回为200,对于成功和响应JSON字符串,JSON结构完全不同.由于状态代码始终为200,因此始终调用onResponse()方法.因此,我无法在错误条件下从JSON中提取错误消息.
解决方案1:
我ScalarsConverterFactory用来获取响应String并手动使用Gson来解析响应.
如何在不使用GSON或android中的任何其他库的情况下使用retrofit获取响应
这个解决方案的问题:我打算使用RxJava2CallAdapterFactory,因为改进方法应该返回DataModel Class.
我需要找到解决此问题的最佳解决方案,我可以继续从Retrofit方法返回数据模型类,并以某种方式从响应中识别错误条件(确定响应JSON与数据模型不匹配)然后解析错误JSON成数据模型.
改造客户
public static Retrofit getClient(String url) {
if (apiClient == null) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient httpClient = new OkHttpClient.Builder().addInterceptor(interceptor).build();
apiClient = new Retrofit.Builder()
.baseUrl(url)
/*addCallAdapterFactory for RX Recyclerviews*/
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
/* add ScalarsConverterFactory to get json string as response */
// .addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
// .addConverterFactory(GsonConverterFactory.create(gson))
.client(httpClient)
.build();
}
return apiClient;
}
Run Code Online (Sandbox Code Playgroud)
方法
public static void getLoginAPIResponse(String username, String password, String sourceId, String uuid, final …Run Code Online (Sandbox Code Playgroud) 嘿,我正在使用Dagger2,Retrofit而且OkHttp我正面临依赖循环问题.
提供时OkHttp:
@Provides
@ApplicationScope
OkHttpClient provideOkHttpClient(TokenAuthenticator auth,Dispatcher dispatcher){
return new OkHttpClient.Builder()
.connectTimeout(Constants.CONNECT_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(Constants.READ_TIMEOUT,TimeUnit.SECONDS)
.writeTimeout(Constants.WRITE_TIMEOUT,TimeUnit.SECONDS)
.authenticator(auth)
.dispatcher(dispatcher)
.build();
}
Run Code Online (Sandbox Code Playgroud)
提供时Retrofit:
@Provides
@ApplicationScope
Retrofit provideRetrofit(Resources resources,Gson gson, OkHttpClient okHttpClient){
return new Retrofit.Builder()
.baseUrl(resources.getString(R.string.base_api_url))
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(okHttpClient)
.build();
}
Run Code Online (Sandbox Code Playgroud)
提供时APIService:
@Provides
@ApplicationScope
APIService provideAPI(Retrofit retrofit) {
return retrofit.create(APIService.class);
}
Run Code Online (Sandbox Code Playgroud)
我的APIService界面:
public interface APIService {
@FormUrlEncoded
@POST("token")
Observable<Response<UserTokenResponse>> refreshUserToken();
--- other methods like login, register ---
}
Run Code Online (Sandbox Code Playgroud)
我的TokenAuthenticator …