在 Android 中使用 Retrofit [英] Using Retrofit in Android

查看:53
本文介绍了在 Android 中使用 Retrofit的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an android app that has 3 activities :

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

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

I have to consume REST Apis. The research I have done so far directs me to use Retrofit. I checked how to use it and found out that :

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

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

Had my app been a single activity app, I would have crunched everything in my MainActivity.java but I don't know how and where to put all the code from steps 1,2,3 for use in my 3 activities.Could you please help by telling how to use Retrofit in my app. Thanks a lot.

具体来说,我需要网络调用:1.登录用户2. 获取用户的所有任务.对于这两种情况,我将使用给定的 REST api.

Specifically, I need network calls to : 1. Login the user 2. Get all the tasks of the user. And for both I would be using a given 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 非常简单明了.

Using Retrofit is quite simple and straightforward.

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

First of all you need to add retrofit to your project, as example with Gradle build sytem.

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

您可以下载 .jar 并将其放入 libs 文件夹的另一种方法.

another way you can download .jar and place it to your libs folder.

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

Then you need to define interfaces that will be used by Retrofit to make API calls to your REST endpoints. For example for users:

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 接口,您可以尝试使用它.

Ok. Now you have defined your API interface an you can try to use it.

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

To start you need to create an instance of RestAdapter and set base url of your API back-end. It's also quite simple:

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

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

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

Here Retrofit will read your information from interface and under the hood it will create RestHandler according to meta-info your provided which actually will perform HTTP requests.

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

Then under the hood, once response is received, in case of json api your data will be transformed to your model using Gson library so you should be aware of that fact that limitations that are present in Gson are actually there in Retrofit.

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

To extend/override process of serialisers/deserialisation your response data to your models you might want to provide your custom serialisers/deserialisers to retrofit.

这里需要实现Converter接口并实现2个方法fromBody()toBody().

Here you need to implement Converter interface and implement 2 methods fromBody() and 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()

And now you need to enable your custom adapters, if it was needed by using setConverter() on building RestAdapter

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

Ok. Now you are aware how you can get your data from server to your Android application. But you need somehow mange your data and invoke REST call in right place. There I would suggest to use android Service or AsyncTask or loader or rx.java that would query your data on background thread in order to not block your UI.

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

So now you can find the most appropriate place to call

SomeUserModel yourUser = yourUsersApi.fetchUser("someUsers")

获取远程数据.

这篇关于在 Android 中使用 Retrofit的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆