簡體   English   中英

Android:如何使用代碼接口設計模式來實現網絡調用庫的多種實現(Retrofit 或 volley)

[英]Android: how to use Code to interface design pattern to have multiple implementations of network call libraries(Retrofit or volley)

我正在從 Head First Design Patterns 學習設計模式,我遇到的第一個模式是“代碼到界面”。現在我想在我的 android 應用程序中使用該模式。我的應用程序包含很多 api 調用。我正在使用 Retrofit用於網絡調用。所以我使用了這種設計模式,考慮到一些類似這樣的場景:
1. 假設將來我需要從 Retrofit 轉向 volley 或任何其他網絡庫。
2. 所以我創建了一個帶有從服務器獲取數據的方法的接口,並創建了一個實現該接口的類。實現的方法包括從服務器獲取數據的改造代碼。
3. 現在,如果我想使用 volley,我將創建一個實現接口的新類,並使用 volley 代碼從服務器檢索數據。
代碼是這樣的

更新

改造特定接口

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

更新

界面

一個具有多個網絡調用庫實現的通用接口(這里我使用的是改造,所以我創建了一個實現這個接口的類 NetworkCallsRetrofitImpl。如果我想切換到 volley,我會創建另一個具有 volley 實現的類並實現這個接口)

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;
}
}

主片段代碼:

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 中,我正在對實現進行硬編碼。如何在這種情況下更好地應用接口設計模式的代碼。謝謝.

更新

這里的“字符串回調”只是一個在收到響應后要調用的方法名稱。這個方法寫在片段類中,視圖必須更新。我正在使用 Java 反射調用這個方法。

1) 帶有回調的方法應該沒有返回類型。 無論如何你都返回 null,所以讓它們無效。

2)您最終將需要在 UI 中返回響應來更新您的視圖,因此您應該將回調作為Callback類傳遞,而不是一些String callback

3) 不需要每次調用您的方法時都更新該私有字段。

4)您不需要 Activity 來發出網絡請求(我想回到第 2 點)

5) 我很確定 Retrofit 使用注釋來處理 URL,所以不確定我在getDataFromServer(url)看到參數的用途。


您更新后的代碼將如下所示。

注意:這不是“編程接口”的展示,也不是任何“設計模式”,它只是“干凈的代碼”(恕我直言)。

無論如何,通過Retrofit.create方法,改造已經強制執行“編程接口”模式。

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());
     }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM