gpt4 book ai didi

java - Android:如何使用代码接口(interface)设计模式来实现网络调用库的多个实现(Retrofit 或 volley)

转载 作者:行者123 更新时间:2023-11-30 00:43:30 27 4
gpt4 key购买 nike

我正在从 Head First Design Patterns 学习设计模式,我遇到的第一个模式是“代码到界面”。现在我想在我的 android 应用程序中使用该模式。我的应用程序包含很多 api 调用。我是使用 Retrofit 进行网络调用。所以我使用了这种设计模式,考虑了一些类似这样的场景:
1. 假设将来我需要从 Retrofit 转移到 volley 或任何其他网络库。
2. 所以我创建了一个接口(interface),其中包含从服务器获取数据的方法,并创建了一个实现该接口(interface)的类。实现的方法包括从服务器获取数据的 Retrofit 代码。
3. 将来如果我想使用 volley,我将创建一个实现该接口(interface)的新类,并使用 volley 代码从服务器检索数据。
代码是这样的

已更新

改造特定接口(interface)

public interface RetrofitApi {
@GET
Call<ResponseBody> getDataFromServer(@Url String url);
}

已更新

界面

一个具有多个网络调用库实现的通用接口(interface)(这里我正在使用改造,所以我创建了一个实现这个接口(interface)的类 NetworkCallsRetrofitImpl。如果我想切换到 volley,我将创建另一个具有 volley 实现的类并实现这个接口(interface))

public interface NetworkCallsApi {
String getDataFromServer(Activity activity,String url,String Callback);
}

改造实现

public class NetworkCallsRetrofitImpl implements NetworkCallsApi{

private Retrofit retrofit;

@Override
public String getDataFromServer(Activity activity, String url, String Callback) {

retrofit = new Retrofit.Builder()
.baseUrl(StringConstants.ROOT_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();

RetrofitApi apiCalls = retrofit.create(RetrofitApi.class);

Call<ResponseBody> call = apiCalls.getDataFromServer(url);

call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {

Method method = null;
try {
method = fragment.getClass().getDeclaredMethod(
Callback, new Class[]{String.class});
method.invoke(fragment, response.body().string());
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}

@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {

}
});
return null;
}
}

服务调用.java

public class ServiceCalls {

public static ServiceCalls serviceCalls;
public NetworkCallsApi networkCallsimpl;

public static ServiceCalls getInstance(){

if(serviceCalls == null){
serviceCalls = new ServiceCalls();
}
return serviceCalls;
}

public void setNetworkCallsimpl(NetworkCallsApi networkCallsimpl) {
this.networkCallsimpl = networkCallsimpl;
}

public String getDataFromServer(Activity activity, String url, String callback){
networkCallsimpl.getDataFromServer(activity,url,callback);
return null;
}
}

主要 fragment 代码:

public class StatusFragment extends Fragment {    

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Setting the implementation
ServiceCalls.getInstance().setNetworkCallsimpl(new NetworkCallsRetrofitImpl());
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

view = inflater.inflate(R.layout.fragment_pnr_status,container,false);

try{
init();
}catch(Exception e){

}
return view;
}

private void init() {

ok.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

setUrlKeysAndValues();
ServiceCalls.getInstance().getDataFromServer(getActivity()
,Utils.getInstance().buildUrl(urlKeys,urlValues),"onResponse");
}
});

}

public void onResponse(String response){

String x = response;
try {
JSONObject jsonObject = new JSONObject(x);
String name = jsonObject.getJSONObject("train").getString("name");
String temp = jsonObject.getJSONObject("train").getString("name");
} catch (JSONException e) {
e.printStackTrace();
}
}
}

现在我的问题是“我是否正确实现了该设计模式”。如果没有,我需要做哪些更改。在 MainFragment 代码的 onCreate 中,我正在对实现进行硬编码。如何更好地应用接口(interface)设计模式代码场景。谢谢。

更新

这里'String Callback'只是一个在收到响应后调用的方法名称。这个方法写在 fragment 类中,必须更新 View 。我使用Java Reflection调用这个方法。

最佳答案

1) 带有回调的方法应该没有返回类型。无论如何你都会返回 null,所以让它们无效。

2) 您最终需要在 UI 中返回响应以更新您的 View ,因此您应该将回调作为 Callback 类传递,而不是某些 String 回调

3) 不需要为每次调用您的方法更新该私有(private)字段。

4) 您不需要 Activity 来发出网络请求(我想回到第 2 点)

5) 我很确定 Retrofit 使用注释来处理 URL,所以不确定我在 getDataFromServer(url) 处看到参数的用途。


更新后的代码如下所示。

注意:这不是“界面编程”或任何“设计模式”的展示,它只是“干净的代码”(恕我直言)。

Retrofit 已经通过Retrofit.create 方法实现了“编程接口(interface)”模式。

public class NetworkCallsRetrofitImpl implements NetworkCallsApi{

private final Retrofit retrofit;

public NetworkCallsRetrofitImpl() {
retrofit = new Retrofit.Builder()
.baseUrl(StringConstants.ROOT_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}

public void getDataFromServer(String url, Callback<ResponseBody> cb) {
retrofit.create(RetrofitApi.class)
.getDataFromServer(url)
.enqueue(cb);
}
}

// This method seems really pointless, by the way... 
public void getDataFromServer(String url, Call<ResponseBody> callback){
networkCallsimpl.getDataFromServer(url,callback);
}

public class StatusFragment extends Fragment implements Callback<ResponseBody> {   

private ServiceCalls serviceCalls;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Setting the implementation
serviceCalls = ServiceCalls.getInstance();
serviceCalls.setNetworkCallsimpl(new NetworkCallsRetrofitImpl());
}

private void updateStatus() {
serviceCalls.getDataFromServer("http://site.example/status", this);
}

@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
String response = response.body().toString();
Toast.makeText(getActivity(), response, TOAST.LENGTH_SHORT).show();
}

@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e("err", t.getMessage());
}
}

关于java - Android:如何使用代码接口(interface)设计模式来实现网络调用库的多个实现(Retrofit 或 volley),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42191359/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com