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

来源:互联网 发布:淘宝没有自然流量 编辑:程序博客网 时间:2024/05/29 17:31

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

public class HttpDemo {        private final Object lock = new Object();        /**         * <Tag, 请求时间>         */        private final Map<String, Long> 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<BasicNameValuePair> 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<BasicNameValuePair> 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。

原创粉丝点击