android - Square Retrofit 重复网络调用

标签 android retrofit

我正在使用 Square 的 Retrofit 库来处理应用程序的网络。我注意到该库无缘无故地重复进行 HTTP 调用,但我真的不知道为什么。

我已验证对接口(interface)方法的调用仅从 Android Activity (即 userAPI.getUserByFacebookIdAsync())执行一次。

有人也尝试过吗?也许与 OKhttp 库设置有关?

非常感谢任何帮助。

改造日志记录

08-18 21:25:56.895  30331-30372/com.package.name D/Retrofit﹕ ---> HTTP GET http://server-instance:8080/server-app//user/facebook?facebookId=00000000
08-18 21:25:56.895  30331-30372/com.package.name D/Retrofit﹕ FacebookId: 00000000
08-18 21:25:56.895  30331-30372/com.package.name D/Retrofit﹕ FacebookToken: XXXXX
08-18 21:25:56.895  30331-30372/com.package.name D/Retrofit﹕ ---> END HTTP (no body)

08-18 21:25:57.434  30331-30372/com.package.name D/Retrofit﹕ ---> HTTP GET http://server-instance:8080/server-app//user/facebook?facebookId=00000000
08-18 21:25:57.434  30331-30372/com.package.name D/Retrofit﹕ FacebookId: 00000000
08-18 21:25:57.434  30331-30372/com.package.name D/Retrofit﹕ FacebookToken: XXXXX
08-18 21:25:57.434  30331-30372/com.package.name D/Retrofit﹕ ---> END HTTP (no body)

08-18 21:25:57.441  30331-30359/com.package.name D/Retrofit﹕ ---> HTTP GET http://server-instance:8080/server-app/user/facebook?facebookId=00000000
08-18 21:25:57.441  30331-30359/com.package.name D/Retrofit﹕ FacebookId: 00000000
08-18 21:25:57.441  30331-30359/com.package.name D/Retrofit﹕ FacebookToken: XXXXX
08-18 21:25:57.441  30331-30359/com.package.name D/Retrofit﹕ ---> END HTTP (no body)

08-19 03:05:59.448  10069-10345/com.package.name D/Retrofit﹕ <--- HTTP 200 http://server-instance:8080/server-app/user/facebook?facebookId=00000000 (770ms)
08-19 03:05:59.448  10069-10345/com.package.name D/Retrofit﹕ : HTTP/1.1 200 OK
08-19 03:05:59.448  10069-10345/com.package.name D/Retrofit﹕ Content-Type: application/json
08-19 03:05:59.448  10069-10345/com.package.name D/Retrofit﹕ Date: Tue, 19 Aug 2014 02:05:59 GMT
08-19 03:05:59.448  10069-10345/com.package.name D/Retrofit﹕ OkHttp-Received-Millis: 1408413959446
08-19 03:05:59.448  10069-10345/com.package.name D/Retrofit﹕ OkHttp-Response-Source: CONDITIONAL_CACHE 200
08-19 03:05:59.448  10069-10345/com.package.name D/Retrofit﹕ OkHttp-Selected-Protocol: http/1.1
08-19 03:05:59.448  10069-10345/com.package.name D/Retrofit﹕ OkHttp-Sent-Millis: 1408413959001
08-19 03:05:59.448  10069-10345/com.package.name D/Retrofit﹕ Server: Apache-Coyote/1.1
08-19 03:05:59.448  10069-10345/com.package.name D/Retrofit﹕ Transfer-Encoding: chunked
08-19 03:05:59.456  10069-10345/com.package.name D/Retrofit﹕ {"id":4,"facebookId":"00000000","gender":"male","city":"Barcelona","country":"Spain","firstName":"John","premium":false}
08-19 03:05:59.456  10069-10345/com.package.name D/Retrofit﹕ <--- END HTTP (390-byte body)

还收到了对额外 2 个调用的响应,它们只是不包含在日志记录示例中。

网络调用(下面进一步包含 Activity 代码)

userAPI.getUserByFacebookIdAsync(user.getId(), new Callback<User>() {
    @Override
    public void success(User user, Response response) {}
    @Override
    public void failure(RetrofitError error) {}

改造API接口(interface)方法

@GET("/user/facebook")
void getUserByFacebookIdAsync(@Query("facebookId") String facebookId, Callback<User> cb);

改造 API 处理程序

public class APIHandler {
static RequestInterceptor requestInterceptor = new RequestInterceptor() {
    @Override
    public void intercept(RequestFacade request) {
        request.addHeader("FacebookId", Constants.FACEBOOK_ID);
        request.addHeader("FacebookToken", Constants.FACEBOOK_TOKEN);
    }
};
private static RestAdapter restAdapter;

private static RestAdapter getRestAdapter() {
    if (restAdapter == null) {
        restAdapter = new RestAdapter.Builder().
                setRequestInterceptor(requestInterceptor).
                setLogLevel(RestAdapter.LogLevel.FULL).
                setClient(Constants.OK_CLIENT).
                setEndpoint(BaseAPI.getInstance().BASE_URL).build();
    }
    return restAdapter;
}

public static UserAPI getUserAPI() {
    UserAPI userAPI = null;
    try {
        if (restAdapter == null) {
            restAdapter = getRestAdapter();
        }
        userAPI = restAdapter.create(UserAPI.class);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return userAPI;
}}

OKHTTP 设置(应用程序启动时)

int cacheSize = 10 * 1024 * 1024; // 10 MiB
File cacheDirectory = new File(getApplicationContext().getCacheDir().getAbsolutePath(), "HttpCache");
Cache cache = null;
try {
    cache = new Cache(cacheDirectory, cacheSize);
} catch (IOException e) {
    e.printStackTrace();
}
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setCache(cache);
Constants.OK_CLIENT = new OkClient(okHttpClient);

Android Activity

public class CurrentUserProfileActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.current_user_profile_activity_layout);

    userAPI = APIHandler.getUserAPI();
    clubAPI = APIHandler.getClubAPI();
    visitAPI = APIHandler.getVisitAPI();

    picasso = PabloPicasso.withDebug(this);

    userProfilePicture = (ImageView) findViewById(R.id.userProfilePicture);

    makeMeRequest(Session.getActiveSession());

    userProfilePicture.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Intent intent = new Intent(getBaseContext(), PictureViewerActivity.class);
            intent.putExtra("facebookId", mUser.getFacebookId());
            startActivity(intent);
            return false;
        }
    });
    }

    private void makeMeRequest(final Session session) {
       Request request = Request.newMeRequest(session,
            new Request.GraphUserCallback() {
                @Override
                public void onCompleted(GraphUser user, com.facebook.Response response) {
                    // If the response is successful
                    if (session == Session.getActiveSession()) {
                        if (user != null) {
                            userAPI.getUserByFacebookIdAsync(user.getId(), new Callback<User>() {
                                @Override
                                public void success(User user, Response response) {
                                    mUser = user;
                               }
                                @Override
                                public void failure(RetrofitError error) {
                                    Log.d(TAG, "userApi call to get User object from server failed!");
                                }
                            });
                        }
                    }
                    if (response.getError() != null) {
                        Intent introActivityIntent = new Intent(CurrentUserProfileActivity.this, IntroActivity.class);
                        introActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                        startActivity(introActivityIntent);
                        finish();
                    }
                }
            }
       );
       request.executeAsync();
    }}

最佳答案

Medium 上有一篇文章,解释了一切

https://medium.com/inloop/okhttp-is-quietly-retrying-requests-is-your-api-ready-19489ef35ace#.mj80t78ir

You can only disable request retrying globally for the whole OkHttpClient instance. This is done by using the OkHttpClient.Builder and setting retryOnConnectionFailure to false.

关于android - Square Retrofit 重复网络调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25371985/

相关文章:

retrofit - NetworkOnMainThread RxJava + 改造 + Lollipop+

在 gradle 文件中包含 Retrolambda 时,Retrofit 2.0 xml simplexml 转换器出现问题

android - 如何为设计支持库的 NavigationView 设置样式?

java - "The following artifacts could not be resolved": Maven/Android/Eclipse

android - 预期为 BEGIN_ARRAY 但在第 1 行第 2 列路径 $ - Retrofit 2 Android 中为 BEGIN_OBJECT

Android Retrofit 2 简单 XML 转换器

android - 在 admob 中使用广告 ID

java - 使用导航选项卡打开相机

java - "This Activity already has an action bar supplied by the window decor..."错误

android - 在空属性上改造 SimpleXMLConverter NumberFormatException