java 在 AsyncTask 中改造调用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29323095/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 15:03:51  来源:igfitidea点击:

Retrofit call inside AsyncTask

javaandroidandroid-asynctaskretrofit

提问by user3159152

I've recently started developing an Android app and decided to use Retrofit as a client of a REST service, but I am not sure if my approach is good:

我最近开始开发 Android 应用程序并决定使用 Retrofit 作为 REST 服务的客户端,但我不确定我的方法是否合适:

i. I've implemented an asynchronous call to my api, which is called inside AsyncTask's doInBackground method. The concern: having read this articlegot me confused. Aren't AsyncTasks suitable for this kind of tasks? Should I make the call to the API directly from the Activity? I understand that Retrofit's callback methods are executed on the UI thread, but how about the call over HTTP? Does Retrofit create threads for that?

一世。我已经实现了对我的 api 的异步调用,它在 AsyncTask 的 doInBackground 方法中调用。该关注:看了这篇文章让我感到困惑。AsyncTasks 不适合做这种任务吗?我应该直接从 Activity 调用 API 吗?我知道 Retrofit 的回调方法是在 UI 线程上执行的,但是通过 HTTP 调用呢?Retrofit 会为此创建线程吗?

ii. I want the AuthenticationResponse to be saved inside a SharedPreferences object, which doesn't seem to be available inside the success method of the callback. Any suggestions/ good practices?

ii. 我希望将 AuthenticationResponse 保存在 SharedPreferences 对象中,该对象在回调的成功方法中似乎不可用。任何建议/良好做法?

Thank you in advance :)

先感谢您 :)

Here's my doInBackGroundMethod:

这是我的 doInBackGroundMethod:

    @Override
    protected String doInBackground(String... params) {
        Log.d(LOCATION_LOGIN_TASK_TAG, params[0]);

        LocationApi.getInstance().auth(new AuthenticationRequest(params[0]), new Callback<AuthenticationResponse>() {

            @Override
            public void success(AuthenticationResponse authenticationResponse, Response response) {
                Log.i("LOCATION_LOGIN_SUCCESS", "Successfully logged user into LocationAPI");
            }

            @Override
            public void failure(RetrofitError error) {
                Log.e("LOCATION_LOGIN_ERROR", "Error while authenticating user in the LocationAPI", error);
            }
        });
        return null;
    }

回答by Konrad Krakowiak

I. Retrofit supports three ways to make a request:

一、Retrofit支持三种请求方式:

  • synchronic
  • 同步的

You have to declare method which returns response as value for example:

您必须声明将响应作为值返回的方法,例如:

  @GET("/your_endpoint")
  AuthenticationResponse auth(@Body AuthenticationRequest authRequest);

This method is done in the thread in which is called. So you can't call it in main/UI thread.

该方法在被调用的线程中完成。所以你不能在 main/UI thread 中调用它

  • asynchronous
  • 异步

You have to declare void method which contains callback with response as last param for example:

您必须声明 void 方法,该方法包含以响应作为最后一个参数的回调,例如:

  @GET("/your_endpoint")
  void auth(@Body AuthenticationRequest authRequest, Callback<AuthenticationResponse> callback);

The execution of request is called in new background thread and the callback methods are done in the thread which method is called, so you can call this method in main/UI thread without new thread/AsyncTask.

请求的执行在新的后台线程中调用,回调方法在调用方法的线程中完成,因此您可以在主/UI线程中调用此方法而无需新线程/AsyncTask。

  • Using RxAndroid
  • 使用 RxAndroid

The last way which I know is method which uses RxAndroid. You have to declare method which returns response as observable with value. For example:

我知道的最后一种方法是使用 RxAndroid 的方法。您必须声明将响应返回为可观察值的方法。例如:

  @GET("/your_endpoint")
  Observable<AuthenticationResponse> auth(@Body AuthenticationRequest authRequest);

This method also supports to make network request in new thread. So you don't have to create new thread/AsyncTask. The Action1 callback from subscribe method is called in UI/main thread.

该方法还支持在新线程中发起网络请求。所以你不必创建新的线程/AsyncTask。来自 subscribe 方法的 Action1 回调在 UI/主线程中调用。

II. You can call your method just in Activity and you can write your data to SharedPreferences as is shown below:

二、您可以仅在 Activity 中调用您的方法,您可以将数据写入 SharedPreferences,如下所示:

SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
sharedPreferences.edit()
            .put...//put your data from AuthenticationResponse 
                   //object which is passed as params in callback method.
            .apply();