【问题标题】:How to save Retrofit 2 response into SharedPreferences如何将 Retrofit 2 响应保存到 SharedPreferences
【发布时间】:2017-10-25 04:08:45
【问题描述】:

我有一个改造 2 响应,通过它我从服务器获取数据。我的代码运行良好。

但我想使用 SharedPreferences 缓存此响应并保持它直到该活动正在运行并且活动被破坏后。我想从 SharedPreferences 中删除此响应。

这是我的代码:

public class SampleClass {
private DataInterface mListener;

public SampleClass() {
    super();
}

public void getDataForId(final String id) {
    ApiInterface apiInterface = APIClient.getApiInterface();
    Call<MyResponse> call = apiInterface.getResponse();
    call.enqueue(new Callback<MyResponse>() {
        @Override
        public void onResponse(Call<MyResponse> call, Response<MyResponse> response) {
            if (response!=null && response.body() != null && mListener != null) {
                mListener.responseData(response.body());
            }
        }
        @Override
        public void onFailure(Call<MyResponse> call, Throwable t) {

        }
    });
}

public void setOnDataListener(DataInterface listener) {
    mListener = listener;
}

public interface DataInterface {
    void responseData( MyResponse myResponse );
}
}

SecondData 类文件

    sampleClass.setOnDataListener(new SampleClass.DataInterface() {
                @Override
                public void responseData(MyResponse myResponse) {
// i wanna store this response into SharedPreferences for temp and delete after activity is destroyed.    

                    List<Detail> details = myResponse.getDetails();
                    for (Detail d : details) {
                        if (d.getId().equals(id)) {
                            reqDetail = d;
                            name.setText(reqDetail.getName());

                           Picasso.with(SecondData.this)
                                    .load(reqDetail.getName())
                                    .placeholder(R.mipmap.ic_launcher)
                                    .error(R.mipmap.ic_launcher)
                                    .into(image);
                        }
                    }
                }
            });

API接口

public interface ApiInterfaceNew {

    @GET("/display.php")
    Call<MyResponse> getResponse();//imp to include MyResponse as a call
}

API 类

private static final String ROOT_URL = "";

    private static Retrofit retrofit1 = null;
    private static final String CACHE_CONTROL = "Cache-Control";

    public static Retrofit getClient() {
        if (retrofit1 == null) {
            retrofit1 = new Retrofit.Builder()
                    .baseUrl(ROOT_URL)
                    .client(provideOkHttpClient())
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit1;
    }

    public static ApiInterfaceNew getApiInterface() {
        return getClient().create(ApiInterfaceNew.class);
    }

    private static OkHttpClient provideOkHttpClient() {
        return new OkHttpClient.Builder()
                .addInterceptor(provideHttpLoggingInterceptor())
                .addInterceptor(provideOfflineCacheInterceptor())
                .addNetworkInterceptor(provideCacheInterceptor())
                .cache(provideCache())
                .build();
    }

    private static Cache provideCache() {
        Cache cache = null;
        try {
            cache = new Cache(new File(AppControler.getInstance().getCacheDir(), "http-cache"),
                    10 * 1024 * 1024); // 10 MB
        } catch (Exception e) {
            Timber.e("Could not create Cache!");
        }
        return cache;
    }

    private static HttpLoggingInterceptor provideHttpLoggingInterceptor() {
        HttpLoggingInterceptor httpLoggingInterceptor =
                new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
                    @Override
                    public void log(String message) {
                        Timber.e(message);
                    }
                });
        httpLoggingInterceptor.setLevel(BuildConfig.DEBUG ? HEADERS : NONE);
        return httpLoggingInterceptor;
    }

    public static Interceptor provideCacheInterceptor() {
        return new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Response response = chain.proceed(chain.request());

                // re-write response header to force use of cache
                CacheControl cacheControl = new CacheControl.Builder()
                        .maxAge(2, TimeUnit.MINUTES)
                        .build();

                return response.newBuilder()
                        .header(CACHE_CONTROL, cacheControl.toString())
                        .build();
            }
        };
    }

    public static Interceptor provideOfflineCacheInterceptor() {
        return new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request = chain.request();

                if (!AppControler.hasNetwork()) {
                    CacheControl cacheControl = new CacheControl.Builder()
                            .maxStale(7, TimeUnit.DAYS)
                            .build();

                    request = request.newBuilder()
                            .cacheControl(cacheControl)
                            .build();
                }

                return chain.proceed(request);
            }
        };
    }

AppControler 类

 public class AppControler extends Application {

        private static AppControler instance;

        @Override
        public void onCreate()
        {
            super.onCreate();

            instance = this;

            if (BuildConfig.DEBUG)
            {
                Timber.plant(new Timber.DebugTree());
            }

            Timber.i("Creating our Application");
        }

        public static AppControler getInstance ()
        {
            return instance;
        }

        public static boolean hasNetwork ()
        {
            return instance.checkIfHasNetwork();
        }

        public boolean checkIfHasNetwork()
        {
            ConnectivityManager cm = (ConnectivityManager) getSystemService( Context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo = cm.getActiveNetworkInfo();
            return networkInfo != null && networkInfo.isConnected();
        }

【问题讨论】:

  • stackoverflow.com/questions/45904054/… 这个答案可能可以帮助您缓存响应。顺便说一下,在 SharedPref 中缓存响应不是一个好主意
  • 嘿,这个代码很累,但我收到了这个错误i.stack.imgur.com/3ZMap.jpg
  • 这里的实例可能没有初始化,为什么它会给出 NullPointerException
  • 嘿兄弟你能告诉我任何解决方案吗?
  • 请至少在该文件中上传整个改造或 okhttp 代码

标签: java android json retrofit2


【解决方案1】:

当响应成功时,在您的改造响应中添加以下代码。

先将JSON转成字符串并存储。

  Gson gson = new Gson();
  String favData = gson.toJson(response.body());

将字符串保存到prefrance。

preferenceManager 是我的 SharedPref 类

  preferenceManager.setStringPreference(Global.OFFLINE_WORD, favData);

现在当你想在下面的方法中调用 pref 数据时。

 public ArrayList<MyResponse> getData(String key) {
    String data = getStringPreference(key);
    Gson gson = new Gson();

    Type type = new TypeToken<ArrayList<MyResponse>>() {
    }.getType();
    return gson.fromJson(data, type);
}

【讨论】:

    【解决方案2】:

    您可以使用 ObjectMapper 或 Gson。

    ObjectMapper 可以参考下面的代码

     public static void updateUserInfo(UserInfo userInfo, Context context) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        Crashlytics.log("updating User Info "+(userInfo!=null?userInfo.toString():"UserInfo is null"));
        final SharedPreferences.Editor edit = preferences.edit();
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            String value = objectMapper.writeValueAsString(userInfo);
            edit.putString("USER_INFO_MODEL", value);
            edit.commit();
        } catch (JsonProcessingException e) {
            Exceptions.propagate(e);
        }
    
    }
    

    您还可以从共享首选项中获取存储的响应

    public static UserInfo getUserInfo(Context context) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        String userDetatails = preferences.getString(AppConstants.USER_INFO_MODEL, "");
        Crashlytics.log("get UserInfo   "+userDetatails);
        ObjectMapper mapper = new ObjectMapper();
        if (StringUtils.isEmpty(userDetatails)) {
            return null;
        }
        UserInfo userInfo = null;
        try {
            userInfo = mapper.readValue(userDetatails, UserInfo.class);
        } catch (IOException e) {
            Exceptions.propagate(e);
        }
        return userInfo;
    }
    

    【讨论】:

    • 我应该在哪里通过改造响应?在这段代码中?
    • 只需调用带有响应和上下文 ClassName 的方法,其中方法可用 CommonUtil.updateUserInfo(response,context);
    猜你喜欢
    • 2015-01-03
    • 2015-03-22
    • 2016-05-27
    • 1970-01-01
    • 2011-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多