【问题标题】:how use volley cache when user offline用户离线时如何使用凌空缓存
【发布时间】:2015-11-20 19:00:41
【问题描述】:

我使用 volley 从本地服务器接收数据,带有 php 和 mysql 数据库。 我的问题是当用户离线时如何使用缓存?

我的 CustomRequest 是这样的:

public class CustomRequest extends Request<JSONArray> {

    private Listener<JSONArray> listener;
    private Map<String, String> params;

    public CustomRequest(int method, String url, Map<String, String> params,
                         Listener<JSONArray> reponseListener, ErrorListener errorListener) {
        super(method, url, errorListener);
        this.listener = reponseListener;
        this.params = params;
    }

    protected Map<String, String> getParams()
            throws com.android.volley.AuthFailureError {
        return params;
    }

    @Override
    protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers));
            return Response.success(new JSONArray(jsonString),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }

    @Override
    protected void deliverResponse(JSONArray response) {
        listener.onResponse(response);
    }
}

NetworkConnection 是这样的:

public class NetworkConnection {
    private static NetworkConnection instance;
    private Context mContext;
    private RequestQueue mRequestQueue;


    public NetworkConnection(Context c){
        mContext = c;
        mRequestQueue = getRequestQueue();
    }


    public static NetworkConnection getInstance( Context c ){
        if( instance == null ){
            instance = new NetworkConnection( c.getApplicationContext() );
        }
        return( instance );
    }


    public RequestQueue getRequestQueue(){
        if( mRequestQueue == null ){
            mRequestQueue = Volley.newRequestQueue(mContext);
        }
        return(mRequestQueue);
    }


    public <T> void addRequestQueue( Request<T> request ){
        getRequestQueue().add(request);
    }


    public void execute( final Transaction transaction, final String tag ){
        WrapObjToNetwork obj = transaction.doBefore();
        Gson gson = new Gson();

        if( obj == null ){
            return;
        }

        HashMap<String, String> params = new HashMap<>();
        params.put("jsonObject", gson.toJson(obj));

        CustomRequest request = new CustomRequest(Request.Method.POST,
            "http://182:168:1:1:8282/new/package/ctrl/CtrlNew.php",

            params,
            new Response.Listener<JSONArray>() {
                @Override
                public void onResponse(JSONArray response) {
                    //Log.i("LOG", tag+" ---> "+response);
                    transaction.doAfter(response);
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.i("LOG", "onErrorResponse(): "+error.getMessage());
                    transaction.doAfter(null);
                }
            });

        request.setTag(tag);
        request.setRetryPolicy(new DefaultRetryPolicy(5000,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

        addRequestQueue(request);
    }
}

这个代码在fargment中

 // NETWORK
        @Override
        public WrapObjToNetwork doBefore() {
            mPbLoad.setVisibility( (mSwipeRefreshLayout != null && mSwipeRefreshLayout.isRefreshing()) ? View.GONE : View.VISIBLE );

            if( UtilTCM.verifyConnection(getActivity()) ){
                Car car = new Car();
                car.setCategory(0);

                if( mList != null && mList.size() > 0 ){
                    car.setId(mSwipeRefreshLayout != null && mSwipeRefreshLayout.isRefreshing() ? mList.get(0).getId() : mList.get(mList.size() - 1).getId());
                }

                return( new WrapObjToNetwork(car, "get-cars", (mSwipeRefreshLayout != null && mSwipeRefreshLayout.isRefreshing()) ) );
            }
            return null;
        }

        @Override
        public void doAfter(JSONArray jsonArray) {
            mPbLoad.setVisibility(View.GONE );

            if( jsonArray != null ){
                CarAdapter adapter = (CarAdapter) mRecyclerView.getAdapter();
                Gson gson = new Gson();
                int auxPosition = 0, position;

                if( mSwipeRefreshLayout != null && mSwipeRefreshLayout.isRefreshing() ){
                    mSwipeRefreshLayout.setRefreshing(false);
                    auxPosition = 1;
                }

                try{
                    for(int i = 0, tamI = jsonArray.length(); i < tamI; i++){
                        Car car = gson.fromJson( jsonArray.getJSONObject( i ).toString(), Car.class );
                        position = auxPosition == 0 ? mList.size() : 0;
                        adapter.addListItem(car, position);

                        if( auxPosition == 1 ){
                            mRecyclerView.getLayoutManager().smoothScrollToPosition(mRecyclerView, null, position);
                        }
                    }

                    if( jsonArray.length() == 0 && auxPosition == 0 ){
                        isLastItem = true;
                    }

                }
                catch(JSONException e){
                    Log.i(TAG, "doAfter(): "+e.getMessage());
                }
            }
            else{
                Toast.makeText(getActivity(), "Falhou. Tente novamente.", Toast.LENGTH_SHORT).show();
            }
        }

请帮忙。 谢谢

【问题讨论】:

  • 你的意思是在离线时,你的应用仍然可以从缓存中获得响应吗?如果我正确理解您的想法,请前往stackoverflow.com/questions/31897189/… 检查我的回答是否有帮助(如果服务器不支持缓存输出)。如果服务器支持缓存,Volley 会自动为你缓存
  • 嗨,是的,我的想法是这样但不适用,我阅读了你的帖子,但我无法解决我的问题。

标签: android caching android-volley


【解决方案1】:

简单的方法是在CustomRequest 方法中编辑您的deliverError,如下所示:

@Override
public void deliverError(VolleyError error) {
    if (error instanceof NoConnectionError) {
        Cache.Entry entry = this.getCacheEntry();
        if(entry != null) {
            Response<T> response = parseNetworkResponse(new NetworkResponse(entry.data, entry.responseHeaders));
            deliverResponse(response.result);
            return;
        }
    } else
         super.deliverError(error);
}

您可以将T 替换为JSONArray 或您在课堂上定义的内容..

【讨论】:

    【解决方案2】:
    //GLobal Functions
    
    public boolean isNetworkAvailable(Activity c) {
            boolean state;
            ConnectivityManager cmg = (ConnectivityManager) c
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo activeNetworkInfo = cmg.getActiveNetworkInfo();
            state = activeNetworkInfo != null && activeNetworkInfo.isConnected();
    
            if (state) {
                return true;
            } else {
                //NO interntet
                return false;
            }
        }
    
    
        public JSONObject getVolleyCacheEntryByUrl(Activity c,
                String relative_url) {
            // RequestQueue queue = Volley.newRequestQueue(c);
            String cachedResponse = new String(AppController
                    .getInstance()
                    .getRequestQueue()
                    .getCache()
                    .get(c.getResources().getString(R.string.base_url)
                            + relative_url).data);
    
            try {
                JSONObject cacheObj = new JSONObject(cachedResponse);
                Log.e("CacheResult", cacheObj.toString());
                return cacheObj;
    
            } catch (JSONException e) {
                e.printStackTrace();
                return null;
            }
    
        }
    
    
    
    //MainActivity
    
    if(isNetworkAvailable(this)) {
        loadDataFromServer();
    } else {
        loadDataFromCache();
    }
    
    
    
    private void loadDataFromCache() {
    
        String url = your-url.com/something;
        if (MyFunctions.chechVolleyCacheByUrl(this, url) != null) {
            try {
                //Your function to parses the data
                parseJson(getVolleyCacheEntryByUrl(
                        this, url));
            } catch (NullPointerException e) {
                //Handle exception
            }
        }
    }
    
    public void loadDattaFromServer() {
    
    
    
        String url = your-url.com/something;
    
        JsonObjectRequest obj = new JsonObjectRequest(
                Request.Method.GET, url, null,
                new Response.Listener<JSONObject>() {
    
                    @Override
                    public void onResponse(JSONObject json) {
                        parseJson(json);
                    }
    
                }, new Response.ErrorListener() {
    
            @Override
            public void onErrorResponse(VolleyError error) {
                VolleyLog.d("volley", "Error: " + error.getMessage());
    
            }
        });
    
        AppController.getInstance().addToRequestQueue(obj);
        obj.setShouldCache(true);
    
    }
    

    以上代码将帮助您解决问题。 注意:此代码使用 volley 库

    【讨论】:

    • 我代替你的代码在我的代码之间并替换它但不起作用。你可以编辑我的代码吗?
    • 什么是 AppController?
    • 其用于创建请求队列的单例类
    猜你喜欢
    • 2016-07-26
    • 2014-08-19
    • 2016-09-19
    • 2023-03-10
    • 2016-01-07
    • 2012-03-09
    • 2019-01-16
    • 1970-01-01
    • 2016-07-04
    相关资源
    最近更新 更多