Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 实现2服务接口_Android_Retrofit_Retrofit2_Android Networking - Fatal编程技术网

Android 实现2服务接口

Android 实现2服务接口,android,retrofit,retrofit2,android-networking,Android,Retrofit,Retrofit2,Android Networking,想象一下下面的场景 我将改型作为我的API客户机,并将使用缓存机制在本地(比如SQLite数据库)保存一些响应,因此一些数据只获得一次。为以下接口创建一个自定义实现似乎是一个完美的例子,该接口将在网络不可用时从本地数据库获取数据 public interface CommentsService { @GET("posts/{postId}/comments") Call<List<Comment>> getCommentsOfPost(@Path("p

想象一下下面的场景

我将改型作为我的API客户机,并将使用缓存机制在本地(比如SQLite数据库)保存一些响应,因此一些数据只获得一次。为以下接口创建一个自定义实现似乎是一个完美的例子,该接口将在网络不可用时从本地数据库获取数据

public interface CommentsService {  
    @GET("posts/{postId}/comments")
    Call<List<Comment>> getCommentsOfPost(@Path("postId") int id);
}
公共接口评论服务{
@获取(“posts/{postId}/comments”)
调用getCommentsOfPost(@Path(“postId”)int-id);
}
问题在于,Refught2中的所有服务方法都应该包装在
Call
对象中,因为它阻止回调作为参数传递,就像以前版本的Refught2一样


我想知道创建此接口的自定义实现是否是一种良好的做法,如果是,那么如何处理调用对象?

在第2部分中,您可以使用
Call.enqueue(Callback)
来指定回调。比如说,

getCommentsService.getCommentsOfPost(myInt).enqueue(new Callback() {
    @Override
    public void onResponse(Call call, Response response) {
        // do something with the response
    }
}

如果您想要同步执行,请使用
Call.execute()

如果您有RxJava的经验,这将变得更容易,因为您可以在获取数据时组合多个任务,并尽快显示数据。因此,首先要做的是将api结果保存到数据库中。下次要显示数据时,可以调用concat方法连接多个源请求(来自缓存、磁盘或服务器),以尽快检索数据

这是一个很好的解释


因为您只想在网络不可用时检查本地数据库,所以您还可以实现一个回调接口,并将其作为参数传递给正在进行改装调用的函数。通过这种方式,您可以使函数返回为void,并且从改装调用的onResonse或onFailure方法内部,您可以决定是从成功响应(onResponse)还是从本地数据库(onFailure)加载,即对自定义接口的所需函数进行所需调用。这将在异步调用中模拟您的改装调用的同步行为,同时使您能够灵活地做出决策,即使您收到不正确的响应。

如果我正确理解您的问题,您希望从SQLite获取数据,以防没有网络连接

您可以使用此接口定义端点:

public interface CommentsService {  
    @GET("posts/{postId}/comments")
    Call<List<Comment>> getCommentsOfPost(@Path("postId") int id);
}
其中CommentsServiceResultListener是传递给前一个接口实现的侦听器。我们将其定义如下:

public interface CommentsServiceResultListener {

    void onResponse(List<Comment> response);

    void onError(String errorMessage);
}
公共接口CommentsServiceResultListener{
无效响应(列表响应);
void onError(字符串错误消息);
}
首先,您需要实现getCommonsService接口,以便实际获取数据。你可以这样做:

public class GetCommensServiceImpl implemens GetCommensService {
    private static final String TAG = BuildingsBaseServiceImpl.class.getSimpleName();

    @Override
    public void getComments(int id, CommentsServiceResultListener listener) {
        CommentsService service = getService();
        Call<List<Comment>> request = service.getCommentsOfPost(id);
        request.enqueue(new Callback<List<Comment>>(){

            @Override  //if this method is executed, the actual call has been made
            public void onResponse(Call<List<Comment>> call, Response<List<Comment>> response) { 
                if (response.isSuccessful()) {
                    listener.onResponse(response.body());
                } else {
                    //TODO check here if the call wans't successful because a network problem. In that case, fetch from your SQLite
                    //Default unsuccessful call management
                    Log.e(TAG, response.code() + ": " + response.message());
                    listener.onError(response.message());
                }
            }

            @Override //maybe the call couldn't be made because of lack of connection. 
            public void onFailure(Call<List<Comment>> call, Throwable t) {
                //TODO check the failure cause, then decide if there's need to fetch from your SQLite.
                //Default failure management
                Log.e(TAG, t.getMessage() + "", t);
                listener.onError(t.getMessage() + "");
            }
        });
    }

    private CommentsService getService() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://your.base.url/")
                .addConverterFactory(GsonConverterFactory.create()) //assuming JSON
                .build();
        return retrofit.create(CommentsService.class);
    }
}
公共类GetCommonsService实现GetCommonsService{
私有静态最终字符串标记=BuildingsBaseServiceImpl.class.getSimpleName();
@凌驾
public void getComments(int-id,CommentsServiceResultListener侦听器){
CommentsService=getService();
调用请求=service.getCommentsOfPost(id);
request.enqueue(新回调(){
@Override//如果执行此方法,则实际调用已完成
public void onResponse(调用调用,响应响应){
if(response.issusccessful()){
onResponse(response.body());
}否则{
//TODO在此检查是否由于网络问题而导致WAN调用失败。在这种情况下,请从SQLite获取
//默认不成功呼叫管理
Log.e(标记,response.code()+”:“+response.message());
listener.onError(response.message());
}
}
@Override//可能由于缺少连接而无法进行呼叫。
失败时公共无效(调用调用,可丢弃的t){
//TODO检查失败原因,然后决定是否需要从SQLite获取。
//默认故障管理
Log.e(标记,t.getMessage()+“”,t);
listener.onError(t.getMessage()+);
}
});
}
私有评论服务getService(){
改装改装=新改装.Builder()
.baseUrl(“http://your.base.url/")
.addConverterFactory(GsonConverterFactory.create())//假设为JSON
.build();
返回改装.create(CommentsService.class);
}
}

希望这有帮助

好吧,让我们设想一下,改造还提供了一种机制(例如,如果从DB加载错误,则通过传递特殊回调)。这将非常具体,因为:

  • 如果我想更新令牌,用于安全数据
  • 如果我想手动重新检查连接
  • 如果我想显示特殊数据
使用改造的主要任务是从连接和工作状态中获得结果。仅此而已

也回答你的问题。在没有网络连接的情况下,您可以提供自己的行为,并调用onDataBaseLoadIfError()。然后调用覆盖的改装类-调用

public interface CommentsServiceListener {

    void onResponse(List<Comment> response);

    void onError(String errorMessage);

    void onDataBaseLoadIfError(String errorMessage);
}
公共接口CommentsServiceListener{
无效响应(列表响应);
void onError(字符串错误消息);
void onDataBaseLoadIfError(字符串错误消息);
}

在我的一个项目中,我遇到了类似的问题,无法使用RxJava。我通过使用命令模式解决了这个问题

首先,我创建了一个带有清晰API的自定义回调类。这样我可以更简洁地处理HTTP代码(例如400或500)

这样,您将实现命令界面并使用它,而不是直接使用改装对象。例如,您可以创建一个
public interface CommentsServiceListener {

    void onResponse(List<Comment> response);

    void onError(String errorMessage);

    void onDataBaseLoadIfError(String errorMessage);
}
public abstract class RestCallback<T> implements Callback<T> {

    @Override
    public void onResponse(Response<T> response, Retrofit retrofit) {
        if (response != null) {
            if (response.isSuccess()) {
                onSuccess(response, retrofit);
            } else {
                onError(response, retrofit);
            }
        } else {
            onFailure(null);
        }
    }

    abstract public void onSuccess(Response<T> response, Retrofit retrofit);

    abstract public void onError(Response<T> response, Retrofit retrofit);

    abstract public void onFailure(Throwable t);

}
public interface Command {

    // New network hit
    void fresh(RestCallback callback);

    // First cached if available then fresh
    void all(RestCallback callback);

    // Cached response only
    void cached(RestCallback callback);

    // If cache exists return it, otherwise return a fresh response
    void get(RestCallback callback);

    // Cancel the request
    void cancel();

}