EDIT 2 (Ekim 2017):
Yıl 2017. Sadece Retrofit kullanın. Başka bir şey kullanmak için neredeyse hiçbir neden yok.
DÜZENLE:
Orijinal yanıt, bu düzenleme sırasında bir buçuk yıldan fazladır. Orijinal yanıtta sunulan kavramlar hala geçerli olsa da, diğer yanıtların da işaret ettiği gibi, artık bu görevi sizin için kolaylaştıran kütüphaneler var. Daha da önemlisi, bu kitaplıklardan bazıları sizin için aygıt yapılandırma değişikliklerini ele alır.
Orijinal cevap referans için aşağıda saklanmıştır. Ancak, kullanım senaryolarınıza uyup uymadıklarını görmek için lütfen Android için Rest istemci kitaplıklarından bazılarını incelemeye zaman ayırın. Aşağıda değerlendirdiğim bazı kütüphanelerin bir listesi yer almaktadır. Hiçbir şekilde kapsamlı bir liste olması amaçlanmamıştır.
Orijinal Cevap:
Android'de REST istemcilere sahip olma yaklaşımımı sunuyorum. Yine de en iyisi olduğunu iddia etmiyorum :) Ayrıca, ihtiyacıma yanıt olarak bulduğum şeyin bu olduğunu unutmayın. Kullanım durumunuz gerektiriyorsa daha fazla katmana sahip olmanız / daha fazla karmaşıklık eklemeniz gerekebilir. Örneğin, yerel depolama alanım yok; çünkü uygulamam birkaç REST yanıtının kaybına tahammül edebiliyor.
Benim yaklaşımım sadece AsyncTask
kapakların altında s kullanıyor . Benim durumumda, bu Görevleri örneğimden "çağırıyorum" Activity
; ancak ekran döndürme gibi durumları tam olarak hesaba katmak için onları a Service
veya benzeri bir yerden aramayı seçebilirsiniz .
REST istemcimin kendisini bir API olarak bilinçli olarak seçtim. Bu, REST istemcimi kullanan uygulamanın gerçek REST URL'lerinden ve kullanılan veri biçiminden haberdar olmasına gerek olmadığı anlamına gelir.
Müşteri 2 katmana sahip olacaktır:
Üst katman: Bu katmanın amacı, REST API'nin işlevselliğini yansıtan yöntemler sağlamaktır. Örneğin, REST API'nizdeki her URL'ye karşılık gelen bir Java yönteminiz olabilir (hatta iki - biri GET'ler ve biri POST'ler için).
Bu, REST istemci API'sine giriş noktasıdır. Bu, uygulamanın normalde kullanacağı katmandır. Bir singleton olabilir, ancak zorunlu değildir.
REST çağrısının yanıtı bu katman tarafından bir POJO olarak ayrıştırılır ve uygulamaya döndürülür.
Bu, AsyncTask
gerçekten dışarı çıkmak ve bu REST çağrısını yapmak için HTTP istemci yöntemlerini kullanan alt düzey katmandır.
Ek olarak, s'lerin sonucunu AsyncTask
uygulamaya geri bildirmek için bir Geri Arama mekanizması kullanmayı seçtim .
Bu kadar metin yeter. Şimdi biraz kod görelim. Farazi bir REST API URL'si alalım - http://myhypotheticalapi.com/user/profile
En üst katman şu şekilde görünebilir:
/**
* Entry point into the API.
*/
public class HypotheticalApi{
public static HypotheticalApi getInstance(){
//Choose an appropriate creation strategy.
}
/**
* Request a User Profile from the REST server.
* @param userName The user name for which the profile is to be requested.
* @param callback Callback to execute when the profile is available.
*/
public void getUserProfile(String userName, final GetResponseCallback callback){
String restUrl = Utils.constructRestUrlForProfile(userName);
new GetTask(restUrl, new RestTaskCallback (){
@Override
public void onTaskComplete(String response){
Profile profile = Utils.parseResponseAsProfile(response);
callback.onDataReceived(profile);
}
}).execute();
}
/**
* Submit a user profile to the server.
* @param profile The profile to submit
* @param callback The callback to execute when submission status is available.
*/
public void postUserProfile(Profile profile, final PostCallback callback){
String restUrl = Utils.constructRestUrlForProfile(profile);
String requestBody = Utils.serializeProfileAsString(profile);
new PostTask(restUrl, requestBody, new RestTaskCallback(){
public void onTaskComplete(String response){
callback.onPostSuccess();
}
}).execute();
}
}
/**
* Class definition for a callback to be invoked when the response data for the
* GET call is available.
*/
public abstract class GetResponseCallback{
/**
* Called when the response data for the REST call is ready. <br/>
* This method is guaranteed to execute on the UI thread.
*
* @param profile The {@code Profile} that was received from the server.
*/
abstract void onDataReceived(Profile profile);
/*
* Additional methods like onPreGet() or onFailure() can be added with default implementations.
* This is why this has been made and abstract class rather than Interface.
*/
}
/**
*
* Class definition for a callback to be invoked when the response for the data
* submission is available.
*
*/
public abstract class PostCallback{
/**
* Called when a POST success response is received. <br/>
* This method is guaranteed to execute on the UI thread.
*/
public abstract void onPostSuccess();
}
Uygulamanın, doğrudan REST API tarafından döndürülen JSON veya XML'yi (veya başka bir biçimi) kullanmadığını unutmayın. Bunun yerine, uygulama yalnızca fasulyeyi görür Profile
.
Ardından, alt katman (AsyncTask katmanı) şu şekilde görünebilir:
/**
* An AsyncTask implementation for performing GETs on the Hypothetical REST APIs.
*/
public class GetTask extends AsyncTask<String, String, String>{
private String mRestUrl;
private RestTaskCallback mCallback;
/**
* Creates a new instance of GetTask with the specified URL and callback.
*
* @param restUrl The URL for the REST API.
* @param callback The callback to be invoked when the HTTP request
* completes.
*
*/
public GetTask(String restUrl, RestTaskCallback callback){
this.mRestUrl = restUrl;
this.mCallback = callback;
}
@Override
protected String doInBackground(String... params) {
String response = null;
//Use HTTP Client APIs to make the call.
//Return the HTTP Response body here.
return response;
}
@Override
protected void onPostExecute(String result) {
mCallback.onTaskComplete(result);
super.onPostExecute(result);
}
}
/**
* An AsyncTask implementation for performing POSTs on the Hypothetical REST APIs.
*/
public class PostTask extends AsyncTask<String, String, String>{
private String mRestUrl;
private RestTaskCallback mCallback;
private String mRequestBody;
/**
* Creates a new instance of PostTask with the specified URL, callback, and
* request body.
*
* @param restUrl The URL for the REST API.
* @param callback The callback to be invoked when the HTTP request
* completes.
* @param requestBody The body of the POST request.
*
*/
public PostTask(String restUrl, String requestBody, RestTaskCallback callback){
this.mRestUrl = restUrl;
this.mRequestBody = requestBody;
this.mCallback = callback;
}
@Override
protected String doInBackground(String... arg0) {
//Use HTTP client API's to do the POST
//Return response.
}
@Override
protected void onPostExecute(String result) {
mCallback.onTaskComplete(result);
super.onPostExecute(result);
}
}
/**
* Class definition for a callback to be invoked when the HTTP request
* representing the REST API Call completes.
*/
public abstract class RestTaskCallback{
/**
* Called when the HTTP request completes.
*
* @param result The result of the HTTP request.
*/
public abstract void onTaskComplete(String result);
}
Bir uygulamanın API'yi ( Activity
veya içinde Service
) nasıl kullanabileceği aşağıda açıklanmıştır :
HypotheticalApi myApi = HypotheticalApi.getInstance();
myApi.getUserProfile("techie.curious", new GetResponseCallback() {
@Override
void onDataReceived(Profile profile) {
//Use the profile to display it on screen, etc.
}
});
Profile newProfile = new Profile();
myApi.postUserProfile(newProfile, new PostCallback() {
@Override
public void onPostSuccess() {
//Display Success
}
});
Umarım yorumların tasarımı açıklamak için yeterlidir; ama daha fazla bilgi vermekten memnuniyet duyarım.