在 Android 中使用改造

Posted

技术标签:

【中文标题】在 Android 中使用改造【英文标题】:Using Retrofit in Android 【发布时间】:2014-12-17 11:09:51 【问题描述】:

我有一个有 3 个活动的 android 应用:

    登录活动 显示与用户相关的所有任务的任务活动(使用阵列适配器填充) 通过单击列表中的任务产生的 task_details 活动

我必须使用 REST API。到目前为止,我所做的研究指导我使用 Retrofit。我检查了如何使用它,发现:

    在主活动中设置基本 URL(我的是登录活动) 我需要创建一个 API 类并使用注释定义我的函数。 在 Activity 中使用类 Rest Adapter 并定义回调。

如果我的应用是单一活动应用,我会处理 MainActivity.java 中的所有内容,但我不知道如何以及将步骤 1、2、3 中的所有代码放在我的 3 个活动中使用的位置。您能否通过告诉我如何在我的应用程序中使用 Retrofit 来提供帮助。非常感谢。

具体来说,我需要网络调用: 1.登录用户 2.获取用户的所有任务。 对于两者,我都会使用给定的 REST api。

*********************************************
          Calling Api USing Retrofit
*********************************************
**Dependancies** :-
      implementation 'com.android.support:recyclerview-v7:27.1.1'
        implementation 'com.squareup.picasso:picasso:2.5.2'
        implementation 'com.android.support:cardview-v7:27.1.1'
    enter code here
**Model**
use the Pozo class

**Api Call**
 -> getLogin()    // use the method



  //API call for Login
    private void getLogin()
    
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
        AsyncHttpClient client = new AsyncHttpClient();
        RequestParams requestParams = new RequestParams();
        requestParams.put("email_id", edit_email.getText().toString());
        requestParams.put("password", edit_password.getText().toString());
        Log.e("", "LOGIN URL==>" + Urls.LOGIN + requestParams);
        Log.d("device_token", "Device_ Token" + FirebaseInstanceId.getInstance().getToken());
        client.post(Urls.LOGIN, requestParams, new JsonHttpResponseHandler() 
            @Override
            public void onStart() 
                super.onStart();
                ShowProgress();
            

            @Override
            public void onFinish() 
                super.onFinish();
                Hideprogress();

            

            @Override
            public void onSuccess(int statusCode, Header[] headers, JSONObject response) 
                super.onSuccess(statusCode, headers, response);
                Log.e("", "Login RESPONSE-" + response);
                Login login = new Gson().fromJson(String.valueOf(response), Login.class);
                edit_email.setText("");
                edit_password.setText("");
                if (login.getStatus().equals("true")) 
                    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
                    MDToast mdToast = MDToast.makeText(SignInActivity.this, String.valueOf("User Login Successfully!"),
                            MDToast.LENGTH_SHORT, MDToast.TYPE_SUCCESS);
                    mdToast.show();
                    Utils.WriteSharePrefrence(SignInActivity.this, Util_Main.Constant.EMAIL, login.getData().getEmailId());
                    Utils.WriteSharePrefrence(SignInActivity.this, Constant.USERID, login.getData().getId());

                    Utils.WriteSharePrefrence(SignInActivity.this, Constant.USERNAME, login.getData().getFirstName());
                    Utils.WriteSharePrefrence(SignInActivity.this, Constant.PROFILE, login.getData().getProfileImage());
                    hideKeyboard(SignInActivity.this);
                    Intent intent = new Intent(SignInActivity.this, DashboardActivity.class);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                    startActivity(intent);
                    finish();
                 else 
                    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
                    MDToast mdToast = MDToast.makeText(SignInActivity.this, String.valueOf("Login Denied"),
                            MDToast.LENGTH_SHORT, MDToast.TYPE_ERROR);
                    mdToast.show();
                
            

            @Override
            public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) 
                super.onFailure(statusCode, headers, responseString, throwable);
                Log.e("", throwable.getMessage());
                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
                MDToast mdToast = MDToast.makeText(SignInActivity.this, "Something went wrong",
                        MDToast.LENGTH_SHORT, MDToast.TYPE_ERROR);
                mdToast.show();
            
        );
    

【问题讨论】:

我没有找到足够的文档/教程来使用 Retrofit。 你解决了吗? 最好使用 volley 进行快速联网。 聚会有点晚了,但对于未来的搜索者:您可以找到相当广泛的改造指南here。 【参考方案1】:

使用 Retrofit 非常简单明了。

首先,您需要为您的项目添加改造,例如 Gradle 构建系统。

compile 'com.squareup.retrofit:retrofit:1.7.1' |

您可以通过另一种方式下载 .jar 并将其放置到您的 libs 文件夹中。

然后您需要定义接口,Retrofit 将使用这些接口对您的 REST 端点进行 API 调用。例如对于用户:

public interface YourUsersApi 

   //You can use rx.java for sophisticated composition of requests 
   @GET("/users/user")
   public Observable<SomeUserModel> fetchUser(@Path("user") String user);

   //or you can just get your model if you use json api
   @GET("/users/user")
   public SomeUserModel fetchUser(@Path("user") String user);

   //or if there are some special cases you can process your response manually 
   @GET("/users/user")
   public Response fetchUser(@Path("user") String user);


好的。现在您已经定义了 API 接口,您可以尝试使用它。

首先,您需要创建一个 RestAdapter 实例并设置 API 后端的基本 url。也很简单:

RestAdapter restAdapter = new RestAdapter.Builder()
   .setEndpoint("https://yourserveraddress.com")
    .build();

YourUsersApi yourUsersApi = restAdapter.create(YourUsersApi.class);

Retrofit 将从界面读取您的信息,并在后台根据您提供的元信息创建 RestHandler,该元信息实际上将执行 HTTP 请求。

然后在后台,一旦收到响应,在 json api 的情况下,您的数据将使用 Gson 库转换为您的模型,因此您应该意识到 Gson 中存在的限制实际上在 Retrofit 中存在。

要将您的响应数据扩展/覆盖序列化器/反序列化过程到您的模型,您可能需要提供自定义序列化器/反序列化器进行改造。

这里需要实现Converter接口,实现fromBody()toBody()两个方法。

这里是例子:

public class SomeCustomRetrofitConverter implements Converter 

    private GsonBuilder gb;

    public SomeCustomRetrofitConverter() 
        gb = new GsonBuilder();

        //register your cursom custom type serialisers/deserialisers if needed
        gb.registerTypeAdapter(SomeCutsomType.class, new SomeCutsomTypeDeserializer());
    

    public static final String ENCODING = "UTF-8";

    @Override
    public Object fromBody(TypedInput body, Type type) throws ConversionException 
        String charset = "UTF-8";
        if (body.mimeType() != null) 
            charset = MimeUtil.parseCharset(body.mimeType());
        
        InputStreamReader isr = null;
        try 
           isr = new InputStreamReader(body.in(), charset);
           Gson gson = gb.create();
           return gson.fromJson(isr, type);
         catch (IOException e) 
            throw new ConversionException(e);
         catch (JsonParseException e) 
            throw new ConversionException(e);
         finally 
            if (isr != null) 
                   try 
                      isr.close();
                    catch (IOException ignored) 
                
            
        
    

    @Override
    public TypedOutput toBody(Object object) 
        try 
            Gson gson = gb.create();
            return new JsonTypedOutput(gson.toJson(object).getBytes(ENCODING), ENCODING);
         catch (UnsupportedEncodingException e) 
            throw new AssertionError(e);
        
     

    private static class JsonTypedOutput implements TypedOutput 
        private final byte[] jsonBytes;
        private final String mimeType;

        JsonTypedOutput(byte[] jsonBytes, String encode) 
            this.jsonBytes = jsonBytes;
            this.mimeType = "application/json; charset=" + encode;
        

        @Override
        public String fileName() 
            return null;
        

       @Override
       public String mimeType() 
           return mimeType;
       

       @Override
       public long length() 
          return jsonBytes.length;
       

       @Override
       public void writeTo(OutputStream out) throws IOException 
           out.write(jsonBytes);
       
    
 

现在您需要启用您的自定义适配器,如果需要的话,可以在构建 RestAdapter 时使用 setConverter()

好的。现在您知道如何将数据从服务器获取到您的 Android 应用程序。但是您需要以某种方式管理您的数据并在正确的位置调用 REST 调用。 在那里,我建议使用 android Service 或 AsyncTask 或 loader 或 rx.java 来在后台线程上查询您的数据,以免阻塞您的 UI。

所以现在你可以找到最合适的地方打电话了

SomeUserModel yourUser = yourUsersApi.fetchUser("someUsers")

获取您的远程数据。

【讨论】:

Unresolved reference: RestAdapter 版本 2 中似乎不再使用 RestAdapter。这个问题有助于解释:***.com/questions/32424184/… 这是改造 1。人们现在正在使用改造 2。语法不同。 一键在您的项目中添加改造的简单方法。 (一次性设置)medium.com/@mestri.vinayak.n/…【参考方案2】:

我刚刚使用了几个星期的改造,起初我发现它很难在我的应用程序中使用。我想与您分享在您的应用程序中使用改造的最简单方法。稍后,如果您已经很好地掌握了改造,您可以增强您的代码(将您的 ui 与 api 分离并使用回调),也许可以从上面的帖子中获得一些技术。

在您的应用中,您有登录、任务列表的活动以及查看详细任务的活动。

首先你需要在你的应用中添加改造,有两种方法,按照上面的@artemis帖子。

Retrofit 使用接口作为您的 API。所以,创建一个接口类。

public interface MyApi

/*LOGIN*/
@GET("/api_reciever/login") //your login function in your api
public void login(@Query("username") String username,@Query("password") String password,Callback<String> calback); //this is for your login, and you can used String as response or you can use a POJO, retrofit is very rubust to convert JSON to POJO

/*GET LIST*/
@GET("/api_reciever/getlist") //a function in your api to get all the list
public void getTaskList(@Query("user_uuid") String user_uuid,Callback<ArrayList<Task>> callback); //this is an example of response POJO - make sure your variable name is the same with your json tagging

/*GET LIST*/
@GET("/api_reciever/getlistdetails") //a function in your api to get all the list
public void getTaskDetail(@Query("task_uuid") String task_uuid,Callback<Task> callback);   //this is an example of response POJO - make sure your variable name is the same with your json tagging


创建另一个接口类来保存 api 的所有 BASE ADDRESS

public interface Constants
   public String URL = "www.yoururl.com"

在您的登录活动中创建一个处理改造的方法

private void myLogin(String username,String password)

RestAdapter restAdapter = new RestAdapter.Builder()
    .setEndpoint(Constants.URL)  //call your base url
    .build();


MyApi mylogin = restAdapter.create(MyApi.class); //this is how retrofit create your api
mylogin.login(username,password,new Callback<String>() 
        @Override
        public void success(String s, Response response) 
            //process your response if login successfull you can call Intent and launch your main activity

        

        @Override
        public void failure(RetrofitError retrofitError) 
            retrofitError.printStackTrace(); //to see if you have errors
        
    );

在您的 MainActivityList 中

private void myList(String user_uuid)

RestAdapter restAdapter = new RestAdapter.Builder()
    .setEndpoint(Constants.URL)  //call your base url
    .build();


MyApi mytask = restAdapter.create(MyApi.class); //this is how retrofit create your api
mytask.getTaskDetail(user_uuid,new Callback<Task>>() 
        @Override
        public void success(ArrayList<Task> list, Response response) 
            //process your response if successful load the list in your listview adapter

        

        @Override
        public void failure(RetrofitError retrofitError) 
            retrofitError.printStackTrace(); //to see if you have errors
        
    );

在您的详细列表中

private void myDetailed(String task_uuid)

RestAdapter restAdapter = new RestAdapter.Builder()
    .setEndpoint(Constants.URL)  //call your base url
    .build();


MyApi mytask = restAdapter.create(MyApi.class); //this is how retrofit create your api
mytask.getTaskList(task_uuid,new Callback<Task>() 
        @Override
        public void success(Task task, Response response) 
            //process your response if successful do what you want in your task

        

        @Override
        public void failure(RetrofitError retrofitError) 
            retrofitError.printStackTrace(); //to see if you have errors
        
    );

希望这对您有所帮助,尽管它确实是使用改造的最简单方法。

【讨论】:

对不起,如果我的问题很琐碎,但我真的很难开始使用 Retrofit(但进展为零)。我们是否应该有一个类似 php 页面的东西来完成任务? Retrofit 是一个适用于 android 的 REST api,基本上你需要有一个服务器端应用程序,比如 php,你还需要在其中构建你的 api。如果您还没有尝试在 android 中使用 REST 创建简单的移动应用程序,您可以从本教程开始,androidhive.info/2012/01/…。如果你已经有 REST 方面的经验,Retrofit 将是一个很好的库。 谢谢。确实,我已经尝试过了,我可以理解。您创建一个 php 页面,该页面接收您作为 POST 发送的内容并生成 JSON 格式的响应。你有什么接近那个改造教程的东西吗? 它实际上不是一个 php 页面。它应该是一个 api,通常是普通的 php 脚本,它接受 JSON/XML 格式的 POST/GET 等请求。这是一个api的例子。函数 login_post() $email = $this->post('email'); $password = $this->post('密码'); $data = $this->Auth_model->authenticate($email, $password);打印_r($数据); 【参考方案3】:

看看这篇关于将 Retrofit 与 Otto 结合使用的优秀博客,这两个库都来自 Square。

http://www.mdswanson.com/blog/2014/04/07/durable-android-rest-clients.html

基本思想是您将在 Application 类中保存对“存储库”对象的引用。该对象将具有“订阅”rest api 事件请求的方法。收到一个后,它将进行适当的 Retrofit 调用,然后“发布”响应,然后另一个组件(例如发出请求的活动)可以“订阅”该响应。

一旦您正确设置了所有这些,通过您的 rest api 访问数据就变得非常容易。例如,请求数据看起来像这样:

    mBus.post(new GetMicropostsRequest(mUserId));

使用数据看起来像这样:

@Subscribe
public void onGetUserProfileResponse(GetUserProfileResponse event) 
    mView.setUserIcon("http://www.gravatar.com/avatar/" + event.getGravatar_id());
    mView.setUserName(event.getName());


这需要一些前期工作,但最终通过 Rest 从我们的后端访问您需要的任何内容变得“微不足道”。

【讨论】:

【参考方案4】:

您可以尝试在应用程序类中保存对您的 api 的引用。然后你可以从任何活动或片段中获取它的实例并从那里获取 api。这听起来有点奇怪,但它可能是一个简单的 DI 替代方案。如果你只在你的应用类中存储引用,它就不会是一种上帝对象

UPD:http://square.github.io/retrofit/ - 这是一些文档,可能有用

【讨论】:

【参考方案5】:

使用 RetroFit 非常简单。

在 build.gradle 中添加依赖。

    compile 'com.squareup.retrofit:retrofit:1.9.0'

    compile 'com.squareup.okhttp:okhttp:2.4.0' 

为所有 http 方法创建一个接口。

复制您的 json 输出并创建 pojo 类以接收您的 json 回复,你可以从JsonSchema2pojo 网站做pojo。

制作一个适配器并调用你的方法

如需完整演示,请尝试本教程Retrofit Android example

【讨论】:

【参考方案6】:

查看此应用程序,该应用程序演示了 Retrofit 与 Google Tasks API 的集成。

https://github.com/sschendel/SyncManagerAndroid-DemoGoogleTasks

有在MainActivity的Activity AsyncTask中使用Retrofit api(TaskApi)的例子,也有在后台服务的Sync Adapter中使用的例子。

@nPn 的答案中发布的文章中的策略可能是一个更优雅的解决方案,但您至少可以看看另一个工作示例。

【讨论】:

【参考方案7】:

首先,将所有内容都放在 MainActivity 中是不好的做法,您最终会得到 God object。

Retrofit site 上的文档非常棒,因此我将阅读您关于如何构建项目的问题。我为演示目的编写了一个非常小的应用程序。它从 cat API 加载猫,并且应该很容易跟踪正在发生的事情。

它有一个使用 JSON 或 XML 来解析来自服务的数据的示例。你可以在https://github.com/codepath/android_guides/wiki/Consuming-APIs-with-Retrofit找到它

希望你能推断出我为什么要按照我的方式构建它。我很乐意回答您在 cmets 中的任何问题并更新答案。

【讨论】:

【参考方案8】:

我觉得这些教程 AndroidHive , CodePath 很有帮助

我将简要描述一下我学到了什么。

第 1 步: 将这三个 dependencies to build.gradle 添加并将 Internet permission 添加到 Manifest

compile 'com.google.code.gson:gson:2.6.2' // for string to class conversion. Not Compulsory
compile 'com.squareup.retrofit2:retrofit:2.1.0'// compulsory
compile 'com.squareup.retrofit2:converter-gson:2.1.0' //for retrofit conversion

在清单中添加它们

<uses-permission android:name="android.permission.INTERNET" />

第 2 步 创建 ApiClient 和 ApiInterface。

public class ApiClient 

    public static final String BASE_URL = "http://yourwebsite/services/";
    private static Retrofit retrofit = null;

    public static Retrofit getClient() 
        if (retrofit==null) 
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        
        return retrofit;
    

在哪里 ApiInterface.class

public interface ApiInterface 

    // getting same data in three different ways.
    @GET("GetCompanyDetailByID")
    Call<CompanyResponse> getDetailOfComapanies(@Query("CompanyID") int companyID);


    @GET("GetCompanyDetailByID")
    Call<ResponseBody> getRawDetailOfCompanies(@Query("CompanyID") int companyID);

    @GET("pathToAdd")
    Call<CompanyResponse> getDetailOfComapaniesWithPath(@Path("pathToAdd") String pathToAppend, @Query("CompanyID") int companyID);

然后像这样调用这个服务

ApiInterface apiService =
                ApiClient.getClient().create(ApiInterface.class);

        Call<CompanyResponse> companyResponseCall = apiService.getDetailOfComapanies(2);
        //Call<CompanyResponse> companyResponseCall = apiService.getDetailOfComapaniesWithPath("GetCompanyDetailByID",2);

        companyResponseCall.enqueue(new Callback<CompanyResponse>() 
            @Override
            public void onResponse(Call<CompanyResponse> call, Response<CompanyResponse> response) 
                CompanyResponse comapnyResponse = response.body();
                Boolean status  = comapnyResponse.getStatus();
            

            @Override
            public void onFailure(Call<CompanyResponse> call, Throwable t) 
            
        );

获取原始 Json 字符串

Call<ResponseBody> call = apiService.getRawDetailOfCompanies(2);
        call.enqueue(new Callback<ResponseBody>() 
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) 
                    String jsonStr = response.body().string();
                    if(!jsonStr.isEmpty())
                        Gson gson = new Gson();

                        JSONObject jObject = new JSONObject(jsonStr).getJSONObject("data");

                        //1st Method
                        Data dataKiType = gson.fromJson(jObject.toString(), Data.class);
                        dataKiType.getCompanyDetail();

                        //2nd method for creaing class or List at runTime
                        Type listType = new TypeToken<Data>().getType();
                        Data yourClassList = new Gson().fromJson(jObject.toString(), listType);
                        yourClassList.getCompanyDetail();
                      e.printStackTrace();
                
            

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

您可以使用http://www.jsonschema2pojo.org/ 通过简单地粘贴 json 来创建您的业务对象。并将源类型选择为 JSON,将注释样式选择为 GSon

【讨论】:

【参考方案9】:

在以下位置找到了一个小而完整且简洁的示例 https://github.com/square/retrofit/tree/master/samples

【讨论】:

【参考方案10】:

初学者发现学习改造并不可怕。我准备了一个教程来简化学习曲线。请参阅Retrofit android tutorial 了解更多信息。

【讨论】:

【参考方案11】:

开发自己的类型安全的 HTTP 库来与 REST API 接口可能是一件非常痛苦的事情:您必须处理许多方面,例如建立连接、缓存、重试失败的请求、线程、响应解析、错误处理等等。另一方面,Retrofit 是一个精心策划、记录并经过测试的库,可以为您节省大量宝贵的时间和麻烦。

编译'com.google.code.gson:gson:2.6.2'

编译'com.squareup.retrofit2:retrofit:2.1.0'//强制

compile 'com.squareup.retrofit2:converter-gson:2.1.0' //用于改造转换

【讨论】:

【参考方案12】:

首先,将此行添加到 gradle 文件中

compile 'com.squareup.retrofit2:retrofit:2.1.0'
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'
    compile 'com.google.code.gson:gson:2.7'
    compile 'com.squareup:otto:1.3.8'
    compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'

然后在Activity的OnCreate中创建对象

HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);    
OkHttpClient client= new OkHttpClient
                .Builder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .addInterceptor(interceptor).build();
Gson gson=new GsonBuilder()
          .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
          .create();
Retrofit retrofit= new Retrofit.Builder()
                .baseUrl("url")
                .client(client)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();

创建一个接口

public interface summaryListAPI 
//post
    @FormUrlEncoded
    @POST("index.php")
    Call<summaryList> post(
            @Field("status") String status,
            @Field("sox") String sox
    );
//get
@GET("yesbdeChatHistoryList/userId/")
    Call<List<ChatTabTwoResp>> getFriends(
            @Path("userId") int userId
    );

创建类

public class summaryList 
    @SerializedName("bookingSummary") @Expose private List<summaryListData> status = new ArrayList<summaryListData>();
   

public class summaryListData 
    @SerializedName("date") @Expose private String date;

将此方法添加到您的活动中

 public void apiSummaryListMain(final Retrofit retrofit) 
        retrofit.create(summaryListAPI.class).post("8547861657","100").enqueue(new Callback<summaryList>() 
            @Override
            public void onResponse(Call<summaryList> call, Response<summaryList> response) 
                if (response.isSuccessful()) 
                    progressBar.setVisibility(View.INVISIBLE);
                     List<summaryListData> summary_List= response.body().getStatus();                   
                else              
                
            
            @Override
            public void onFailure(Call<summaryList> call, Throwable t) 

            
        );

    

【讨论】:

【参考方案13】:

它的工作原理

包 com.keshav.gmailretrofitexampleworking.network;

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class ApiClient 
    public static final String BASE_URL = "http://api.androidhive.info/json/";
    private static Retrofit retrofit = null;

    public static Retrofit getClient() 
        if (retrofit == null) 
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        
        return retrofit;
    

==============================================
package com.keshav.gmailretrofitexampleworking.network;

import com.keshav.gmailretrofitexampleworking.models.Message;

import java.util.List;

import retrofit2.Call;
import retrofit2.http.GET;

public interface ApiInterface 
    @GET("inbox.json")
    Call<List<Message>> getInbox();

编译'com.google.code.gson:gson:2.6.2'

compile 'com.squareup.retrofit2:retrofit:2.0.2'

compile 'com.squareup.retrofit2:converter-gson:2.0.2'

================================================ ======

在 onCreate 中调用 Retrofit 2 APi

private void getInbox() 
    swipeRefreshLayout.setRefreshing(true);

    ApiInterface apiService =
            ApiClient.getClient().create(ApiInterface.class);

    Call<List<Message>> call = apiService.getInbox();
    call.enqueue(new Callback<List<Message>>() 
        @Override
        public void onResponse(Call<List<Message>> call, Response<List<Message>> response) 
            // clear the inbox
            messages.clear();

            // add all the messages
            // messages.addAll(response.body());

            // TODO - avoid looping
            // the loop was performed to add colors to each message

            Log.e("keshav","response" +response.body());

            for (Message message : response.body()) 
                // generate a random color

                // TODO keshav Generate Random Color Here
                message.setColor(getRandomMaterialColor("400"));
                messages.add(message);
            

            mAdapter.notifyDataSetChanged();
            swipeRefreshLayout.setRefreshing(false);
        

        @Override
        public void onFailure(Call<List<Message>> call, Throwable t) 
            Toast.makeText(getApplicationContext(), "Unable to fetch json: " + t.getMessage(), Toast.LENGTH_LONG).show();
            swipeRefreshLayout.setRefreshing(false);
        
    );

源代码 https://drive.google.com/open?id=0BzBKpZ4nzNzUVFRnVVkzc0JabUU

https://drive.google.com/open?id=0BzBKpZ4nzNzUc2FBdW00WkRfWW8

【讨论】:

【参考方案14】:

我只是以一种非常简单的方式解决了这个问题,您只需要安装一个插件并按照一些步骤在您的任何应用程序中实施改造即可。:

已发布答案:Retrofit in android?

在您的 Android 工作室中添加(QAssist - Android Studio 插件)Android 插件。 (https://github.com/sakkeerhussain/QAssist)。

希望这会对你有所帮助。

【讨论】:

【参考方案15】:

使用 RxJava 进行简单改造 + okhttp 集成

public WebService apiService(Context context) 
    String mBaseUrl = context.getString(BuildConfig.DEBUG ? R.string.local_url : R.string.live_url);

    int cacheSize = 5 * 1024 * 1024; // 5 MB
    Cache cache = new Cache(context.getCacheDir(), cacheSize);

    HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
    loggingInterceptor.setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE);

    OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .readTimeout(120, TimeUnit.SECONDS)
            .writeTimeout(120, TimeUnit.SECONDS)
            .connectTimeout(120, TimeUnit.SECONDS)
            .addInterceptor(loggingInterceptor)
            //.addNetworkInterceptor(networkInterceptor)
            .cache(cache)
            .build();

    return new Retrofit.Builder().baseUrl(mBaseUrl)
            .client(okHttpClient)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build().create(WebService.class);


【讨论】:

【参考方案16】:

public interface APIService 

    @POST(Constant.updateProfile)
    @FormUrlEncoded
    Call<ResponseBody> updateProfile(
            @Field("user_id") String user_id,
            @Field("first_name") String first_name,
            @Field("last_name") String last_name
    );


public class RetrofitClient 
    private static Retrofit retrofit = null;

    public static Retrofit getClient(String baseUrl) 
        if (retrofit == null) 
            retrofit = new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        
        return retrofit;
    




public class Body 


// Check Status if Status True or False
String status;
String message;
String checksum;
  




public interface OnBodyResponseListner 


public void onSucces(Body response);
public void onFailure(Body response);
public void onBlankBody(Call<ResponseBody> call);



 public static void setOnWebServiceCallListner(final Call<ResponseBody> t, final OnBodyResponseListner onBodyResponseListner) 
    t.enqueue(new Callback<ResponseBody>() 
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) 
            try 
                call.cancel();
                Gson gson = new GsonBuilder().serializeNulls().create();
                String json = response.body().string();
                Log.d(TAG, json + "  ~ Response ~  " + json);
                Body body = gson.fromJson(json, Body.class);

                if (body.getStatus().equalsIgnoreCase("true")) 
                    onBodyResponseListner.onSucces(body);
                 else 
                    onBodyResponseListner.onFailure(body);
                


             catch (Exception e) 
            
        

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) 
            onBodyResponseListner.onBlankBody(call);
            Log.d(TAG, "~ Response Message Blank ~ " + t.getMessage() + " \n Localize Message ~ " + t.getLocalizedMessage() + " \n" + t.getStackTrace().toString());
        
    );





 APIService mService = RetrofitClient.getClient(Constant.BASE_URL).create(APIService.class);


Oprations.setOnWebServiceCallListner(mService.updateProfile("12",
            "first_name",
            "last,name"
    ), new OnBodyResponseListner() 
        @Override
        public void onSucces(Body response) 
            
           

        

        @Override
        public void onFailure(Body response) 
            
            Toast.makeText(mContext, response.getMessage(), Toast.LENGTH_SHORT).show();

        

        @Override
        public void onBlankBody(Call<ResponseBody> call) 

        
    );

【讨论】:

【参考方案17】:
    首先,添加依赖-compile 'com.squareup.retrofit:retrofit:1.7.1' 创建改造实例类
public class RetrofitClientInstance 
    private Context context;
    private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
    private static Retrofit retrofit
    private static Retrofit.Builder builder =
            new Retrofit.Builder()
                    .baseUrl(BuildConfig.SERVER_URL)
                    .client(getRequestHeader())
                    .addConverterFactory(GsonConverterFactory.create());
    public static HttpLoggingInterceptor setLogger() 
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        return logging;
    
    public static <S> S createService(Class<S> serviceClass) 

        if (!httpClient.interceptors().isEmpty()) 

            httpClient.interceptors().clear();
        
        httpClient.authenticator(new AccessTokenAuthenticator());
        httpClient.readTimeout(60,TimeUnit.SECONDS);
        httpClient.connectTimeout(60,TimeUnit.SECONDS);
        httpClient.addInterceptor(setLogger());
        httpClient.addInterceptor(new Interceptor() 
            @Override
            public Response intercept(Chain chain) throws IOException 
                Request original = chain.request();
                Request.Builder requestBuilder = original.newBuilder()
                        .header("LocalSystemDate", MyApplication.getInstance().getCurrentDateAndTimeWithTimeZone())
                        .addHeader("channel_id", AppConst.CHANNEL_ID)
                        .addHeader("Authorization", "Bearer" + " " + SharedPref.getsAccessToken())
                        .method(original.method(), original.body());
                Request request = requestBuilder.build();
                return chain.proceed(request);
            
        );

        OkHttpClient client = httpClient.build();
        Retrofit retrofit = builder.client(client).build();
        return retrofit.create(serviceClass);
    


    private static OkHttpClient getRequestHeader() 

        return new OkHttpClient.Builder()
                .readTimeout(60, TimeUnit.SECONDS)
                .connectTimeout(60, TimeUnit.SECONDS)
                .build();
    


    编写界面
public interface GetDataService 

    @Headers("Content-Type: application/json")
    @POST("login")
    Call<LoginResponseModel> loginUser(
          @Body LoginBodyModel loginBodyModel
    );


    调用服务
GetDataService service = RetrofitClientInstance.createService(GetDataService.class);

Call<LoginResponseModel> loginModelCall = service.loginUser(loginBodyModel);

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

    

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

    
);

【讨论】:

以上是关于在 Android 中使用改造的主要内容,如果未能解决你的问题,请参考以下文章

在模块(android 库)中使用改造 2.4.0 时出现 NoClassDefFoundError

如何在 Kotlin android 的改造中使用 enque 方法

如何在android中使用改造@Query注解进行过滤

在android中使用改造的json解析错误

如何在 android 中使用改造来解析这个 web 服务?

改造返回错误 307,在 android 中调用 web 服务