Android并发网络请求,刚好碰到token失效的处理方案

接口开发一般都有个token验证,2~3小时失效,需要重新登录刷新。
如果客户端有好几个并发的网络请求,刚好这时候token失效了,怎么办呢?
按正常流程,token失效会走自动登录流程,N个并发就会走N次登录,对用户来说可能感觉不大。但是对开发者来说,这种做法只能给自己打60分。
接下来给出自己相对满意的解决方案,注释写的比较清楚,就不做过多解释了。

public class HttpDemo {

        private final Object lock = new Object();

        /**
         * 
         */
        private final Map reqMap = new ConcurrentHashMap<>();

        /**
         * token失效,记录开始刷新时间
         */
        private long flushTokenTime;

        private static HttpDemo mInstance = null;

        private HttpDemo() {
        }

        public static HttpDemo getInstance() {
            if(mInstance==null) {
                synchronized (HttpDemo.class) {
                    if(mInstance==null)
                        mInstance = new HttpDemo();
                }
            }
            return mInstance;
        }

        /**
         * post请求(同步)
         * @param reqTag
         * @param url 访问链接
         * @param parameters 请求参数
         * @return
         */
        public String post(String reqTag, String url, List parameters) {
            ......
            reqMap.put(reqTag, SystemClock.elapsedRealtime());
            return dealReqResult(result, reqTag, url, parameters);
        }

        /**
         * 处理请求结果
         * @param result Json格式
         * @param reqTag
         * @param url
         * @param parameters
         * @return
         */
        private String dealReqResult(String result, String reqTag, String url, List parameters) {
            ......
            if(resCode==3) {    //token失效
                synchronized (lock) {
                    if(reqMap.get(reqTag) < flushTokenTime) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        return post(reqTag, url, parameters);
                    }

                    flushTokenTime = SystemClock.elapsedRealtime();  
                }
                autoLogin();
                return post(reqTag, url, parameters);
            }
            ......
            reqMap.remove(reqTag);
            return result;
        }

        /**
         * 自动登录(同步)
         */
        private void autoLogin() {
            //取本地缓存的账号密码进行登录
            ......

            //刷新token完成
            synchronized (lock) {
                lock.notifyAll();
            }
        }
    }

补充两点:

  • 如果autoLogin()报错了,没有执行到notifyAll(),记得在Activity.onDestory()中把线程停掉(thread.stop()…);

  • post是同步的,在外部需要避免在主线程中调用,防止ANR。

你可能感兴趣的:(Android并发网络请求,刚好碰到token失效的处理方案)