来自iOS开发人员学习Android的两部分问题,研究Android项目,该项目将发出从JSON到图像到音频和视频的流媒体下载的各种请求:
在iOS上,我广泛使用了AFNetworking项目.是否有适用于Android的等效库?
我已经阅读了OkHTTP和Square的改造,以及Volley,但还没有与他们一起开发的经验.我希望有人可以提供一些最佳使用案例的具体例子.从我所看到的,看起来OkHTTP是三者中最强大的,并且可以处理这个项目的要求(如上所述).
我正在尝试获取请求中发送的确切JSON.这是我的代码:
OkHttpClient client = new OkHttpClient();
client.interceptors().add(new Interceptor(){
@Override public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Log.e(String.format("\nrequest:\n%s\nheaders:\n%s",
request.body().toString(), request.headers()));
com.squareup.okhttp.Response response = chain.proceed(request);
return response;
}
});
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client).build();
Run Code Online (Sandbox Code Playgroud)
但我只在日志中看到这个:
request:
com.squareup.okhttp.RequestBody$1@3ff4074d
headers:
Content-Type: application/vnd.ll.event.list+json
Run Code Online (Sandbox Code Playgroud)
我怎么做正确的记录,考虑到拆除setLog()和setLogLevel()我们使用了改造1使用哪个?
这个问题可能以前曾被问过,但没有得到明确答复.如何在Retrofit请求的主体内发布原始整个JSON?
看到类似的问题在这里.或者这个答案是否正确,它必须是url编码形式并作为字段传递?我真的希望不会,因为我所连接的服务只是期待帖子正文中的原始JSON.它们未设置为查找JSON数据的特定字段.
我只是想与澄清这一restperts一劳永逸.一个人回答不使用Retrofit.另一个不确定语法.另一个人认为可以这样做,但只有当它的形式url编码并放在一个字段中时(在我的情况下这是不可接受的).不,我无法为我的Android客户端重新编码所有服务.是的,在主要项目中发布原始JSON而不是将JSON内容作为字段属性值传递是很常见的.让我们做对了,继续前进吧.有人可以指向显示如何完成此操作的文档或示例吗?或者提供可以/不应该完成的有效理由.
更新:我可以100%确定地说一件事.你可以在谷歌的排球中做到这一点.它是内置的.我们可以在Retrofit中做到这一点吗?
我正在为我的应用程序开发网络.所以我决定尝试Square的Retrofit.我看到他们支持简单Callback
@GET("/user/{id}/photo")
void getUserPhoto(@Path("id") int id, Callback<Photo> cb);
Run Code Online (Sandbox Code Playgroud)
和RxJava的 Observable
@GET("/user/{id}/photo")
Observable<Photo> getUserPhoto(@Path("id") int id);
Run Code Online (Sandbox Code Playgroud)
乍一看两者看起来都非常相似,但是当它实现时它变得有趣......
虽然简单的回调实现看起来类似于:
api.getUserPhoto(photoId, new Callback<Photo>() {
@Override
public void onSuccess() {
}
});
Run Code Online (Sandbox Code Playgroud)
这非常简单明了.随着Observable它迅速变得冗长和复杂.
public Observable<Photo> getUserPhoto(final int photoId) {
return Observable.create(new Observable.OnSubscribeFunc<Photo>() {
@Override
public Subscription onSubscribe(Observer<? super Photo> observer) {
try {
observer.onNext(api.getUserPhoto(photoId));
observer.onCompleted();
} catch (Exception e) {
observer.onError(e);
}
return Subscriptions.empty();
}
}).subscribeOn(Schedulers.threadPoolForIO());
}
Run Code Online (Sandbox Code Playgroud)
那不是它.你仍然需要做这样的事情:
Observable.from(photoIdArray)
.mapMany(new Func1<String, Observable<Photo>>() {
@Override
public Observable<Photo> call(Integer s) { …Run Code Online (Sandbox Code Playgroud) 我在我的应用程序中使用Retrofit库,我想将超时设置为60秒.Retrofit有办法做到这一点吗?
我这样设置Retrofit:
RestAdapter restAdapter = new RestAdapter.Builder()
.setServer(BuildConfig.BASE_URL)
.setConverter(new GsonConverter(gson))
.build();
Run Code Online (Sandbox Code Playgroud)
如何设置超时?
使用Retrofit 2,您可以在服务方法的注释中设置完整的URL,如:
public interface APIService {
@GET("http://api.mysite.com/user/list")
Call<Users> getUsers();
}
Run Code Online (Sandbox Code Playgroud)
但是,在我的应用程序中,我的webservices的URL在编译时是未知的,应用程序在下载的文件中检索它们,所以我想知道如何使用Retrofit 2和完整的动态URL.
我试图设置一个完整的路径,如:
public interface APIService {
@GET("{fullUrl}")
Call<Users> getUsers(@Path("fullUrl") fullUrl);
}
new Retrofit.Builder()
.baseUrl("http://api.mysite.com/")
.build()
.create(APIService.class)
.getUsers("http://api.mysite.com/user/list"); // this url should be dynamic
.execute();
Run Code Online (Sandbox Code Playgroud)
但在这里,Retrofit并未发现该路径实际上是一个完整的URL并且正在尝试下载 http://api.mysite.com/http%3A%2F%2Fapi.mysite.com%2Fuser%2Flist
有关如何使用这种动态网址进行Retrofit的任何提示吗?
谢谢
我正在尝试使用Retrofit和OKHttp来缓存HTTP响应.我按照这个要点,结束了这段代码:
File httpCacheDirectory = new File(context.getCacheDir(), "responses");
HttpResponseCache httpResponseCache = null;
try {
httpResponseCache = new HttpResponseCache(httpCacheDirectory, 10 * 1024 * 1024);
} catch (IOException e) {
Log.e("Retrofit", "Could not create http cache", e);
}
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setResponseCache(httpResponseCache);
api = new RestAdapter.Builder()
.setEndpoint(API_URL)
.setLogLevel(RestAdapter.LogLevel.FULL)
.setClient(new OkClient(okHttpClient))
.build()
.create(MyApi.class);
Run Code Online (Sandbox Code Playgroud)
这是带有Cache-Control标头的MyApi
public interface MyApi {
@Headers("Cache-Control: public, max-age=640000, s-maxage=640000 , max-stale=2419200")
@GET("/api/v1/person/1/")
void requestPerson(
Callback<Person> callback
);
Run Code Online (Sandbox Code Playgroud)
首先,我在线请求并检查缓存文件.有正确的JSON响应和标题.但是当我尝试离线请求时,我总是得到RetrofitError UnknownHostException.我还有什么办法让Retrofit从缓存中读取响应吗?
编辑:
因为OKHttp 2.0.x HttpResponseCache是Cache …
我们在Android应用中使用Retrofit与OAuth2安全服务器进行通信.一切都很好,我们使用RequestInterceptor在每次调用时包含访问令牌.但是,有时候,访问令牌将过期,并且需要刷新令牌.当令牌过期时,下一个调用将返回一个未授权的HTTP代码,因此很容易监控.我们可以通过以下方式修改每个Retrofit调用:在失败回调中,检查错误代码,如果它等于Unauthorized,则刷新OAuth令牌,然后重复Retrofit调用.但是,为此,应修改所有呼叫,这不是一个易于维护的好解决方案.有没有办法在不修改所有Retrofit调用的情况下执行此操作?
我正在尝试使用Retrofit 2.0对服务器进行HTTP POST
MediaType MEDIA_TYPE_TEXT = MediaType.parse("text/plain");
MediaType MEDIA_TYPE_IMAGE = MediaType.parse("image/*");
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
imageBitmap.compress(Bitmap.CompressFormat.JPEG,90,byteArrayOutputStream);
profilePictureByte = byteArrayOutputStream.toByteArray();
Call<APIResults> call = ServiceAPI.updateProfile(
RequestBody.create(MEDIA_TYPE_TEXT, emailString),
RequestBody.create(MEDIA_TYPE_IMAGE, profilePictureByte));
call.enqueue();
Run Code Online (Sandbox Code Playgroud)
服务器返回错误,指出文件无效.
这很奇怪,因为我试图在iOS上使用相同的格式上传相同的文件(使用其他库),但它上传成功.
我想知道使用Retrofit 2.0上传图像的正确方法是什么?
在上传之前我应该先将它保存到磁盘吗?
谢谢!
PS:我已经将改造用于其他不包含图像的Multipart请求,并且已成功完成.问题是当我试图在主体中包含一个字节时.
我从使用Volley迁移到Retrofit,我已经拥有了我之前使用的gson类,用于将JSONObject响应转换为实现gson注释的对象.当我尝试使用改造来制作http get请求但我的应用程序崩溃时出现此错误:
Unable to start activity ComponentInfo{com.lightbulb.pawesome/com.example.sample.retrofit.SampleActivity}: java.lang.IllegalArgumentException: Unable to create converter for class com.lightbulb.pawesome.model.Pet
for method GitHubService.getResponse
Run Code Online (Sandbox Code Playgroud)
我遵循改造网站的指南,我想出了这些实现:
这是我尝试执行复古http请求的活动:
public class SampleActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("**sample base url here**")
.build();
GitHubService service = retrofit.create(GitHubService.class);
Call<Pet> callPet = service.getResponse("41", "40");
callPet.enqueue(new Callback<Pet>() {
@Override
public void onResponse(Response<Pet> response) {
Log.i("Response", response.toString());
}
@Override
public void onFailure(Throwable t) {
Log.i("Failure", t.toString());
}
});
try{
callPet.execute();
} …Run Code Online (Sandbox Code Playgroud)