XUtils框架之登录态持久化机制(session保留机制)


            在我们平时使用应用程序时会发现一个问题,我使用应用程序时可能会接电话,或者去切出去看微信等,等在进入应用程序时,程序已经被系统杀掉。如果要继续使用应用程序需要重新登录。这样频繁反复登录会使用户极度烦躁。怎样才能保持登录态持久化就成了我们开发人员必须解决的问题。我们的目标就是想微信那样,登录一次后就算程序被系统杀掉,打开微信后也是登录的状态。


        那具体要怎么做呢

        首先我们要看如果跳过登录直接与服务器通信,服务器之所以知道发来请求的是我而不是别人,是以为我们在与服务器通讯的时候发送了 sessionID,而sessionID又存在了CookieStore的Cookies中。而以XUtils为例发送请求是对Cookies的操作又只有

HttpUtils http = new HttpUtils();

http.configCookieStore(CookieStore);

那如何保存CookieStore就是我们要解决的问题,解决这个问题就可以在程序被系统杀掉后吧保存的CookieStore赋给发送请求就可以达到跳过登录直接和服务器通讯的目的了。


        那如何保存CookieStore呢

        我们分为使用Xutils框架和没有使用Xutils框架分别讲。

        1.使用了XUtils框架

         在XUtils框架代码中com.lidroid.xutils.util下有个PreferencesCookieStore.java

在XUtils发送请求成功的回调中加入:

public void onSuccess(ResponseInfo<String> responseInfo) {
					DefaultHttpClient dh = (DefaultHttpClient) http.getHttpClient();
					CookieStore cs = dh.getCookieStore();
					List<Cookie> cookies = cs.getCookies();
					PreferencesCookieStore preferencesCookieStore = new PreferencesCookieStore(context);
					String aa = null;
					for (int i = 0; i < cookies.size(); i++) {
						if ("JSESSIONID".equals(cookies.get(i).getName())) {
							aa = cookies.get(i).getValue();
							LoginCache.getInstance().setCookieStore(dh.getCookieStore());把CookieStore存入缓存
							//把CookieStore以Cookie形式存入PreferencesCookieStore 
							for (Cookie cookie : cookies) {
								preferencesCookieStore.addCookie(cookie);
								}
							break;
						}
					}      	
		        }

这样就成功存入preferences中了


在在程序启动的入口吧CookieStore取出并赋给缓存

PreferencesCookieStore cookieStore = new PreferencesCookieStore(context);


在给服务器发送请求时做个判断,并在请求中加上CookieStore就达到了登录态持久化,就可以直接通讯了

		final HttpUtils http = new HttpUtils();
		http.configCookieStore(//缓存中刚刚从PreferencesCookieStore中取出的CookieStore);			

         2.没有使用XUtils框架

操作步骤与上面一样只不过需要自定义PreferencesCookieStore类,上代码:

public class PreferencesCookieStore implements CookieStore {

	private static final String COOKIE_PREFS = "CookiePrefsFile";
	private static final String COOKIE_NAME_STORE = "names";
	private static final String COOKIE_NAME_PREFIX = "cookie_";

	private final ConcurrentHashMap<String, Cookie> cookies;
	private final SharedPreferences cookiePrefs;

	/**
	 * Construct a persistent cookie store.
	 */
	public PreferencesCookieStore(Context context) {
		cookiePrefs = context.getSharedPreferences(COOKIE_PREFS,
				Context.MODE_PRIVATE);
		cookies = new ConcurrentHashMap<String, Cookie>();

		// Load any previously stored cookies into the store
		String storedCookieNames = cookiePrefs.getString(COOKIE_NAME_STORE,
				null);
		if (storedCookieNames != null) {
			String[] cookieNames = TextUtils.split(storedCookieNames, ",");
			for (String name : cookieNames) {
				String encodedCookie = cookiePrefs.getString(COOKIE_NAME_PREFIX
						+ name, null);
				if (encodedCookie != null) {
					Cookie decodedCookie = decodeCookie(encodedCookie);
					if (decodedCookie != null) {
						cookies.put(name, decodedCookie);
					}
				}
			}

			// Clear out expired cookies
			clearExpired(new Date());
		}
	}

	@Override
	public void addCookie(Cookie cookie) {
		String name = cookie.getName();

		// Save cookie into local store, or remove if expired
		if (!cookie.isExpired(new Date())) {
			cookies.put(name, cookie);
		} else {
			cookies.remove(name);
		}

		// Save cookie into persistent store
		SharedPreferences.Editor editor = cookiePrefs.edit();
		editor.putString(COOKIE_NAME_STORE,
				TextUtils.join(",", cookies.keySet()));
		editor.putString(COOKIE_NAME_PREFIX + name,
				encodeCookie(new SerializableCookie(cookie)));
		editor.commit();
	}

	@Override
	public void clear() {
		// Clear cookies from persistent store
		SharedPreferences.Editor editor = cookiePrefs.edit();
		for (String name : cookies.keySet()) {
			editor.remove(COOKIE_NAME_PREFIX + name);
		}
		editor.remove(COOKIE_NAME_STORE);
		editor.commit();

		// Clear cookies from local store
		cookies.clear();
	}

	@Override
	public boolean clearExpired(Date date) {
		boolean clearedAny = false;
		SharedPreferences.Editor editor = cookiePrefs.edit();

		for (ConcurrentHashMap.Entry<String, Cookie> entry : cookies.entrySet()) {
			String name = entry.getKey();
			Cookie cookie = entry.getValue();
			if (cookie.getExpiryDate() == null || cookie.isExpired(date)) {
				// Remove the cookie by name
				cookies.remove(name);

				// Clear cookies from persistent store
				editor.remove(COOKIE_NAME_PREFIX + name);

				// We've cleared at least one
				clearedAny = true;
			}
		}

		// Update names in persistent store
		if (clearedAny) {
			editor.putString(COOKIE_NAME_STORE,
					TextUtils.join(",", cookies.keySet()));
		}
		editor.commit();

		return clearedAny;
	}

	@Override
	public List<Cookie> getCookies() {
		return new ArrayList<Cookie>(cookies.values());
	}

	public Cookie getCookie(String name) {
		return cookies.get(name);
	}

	protected String encodeCookie(SerializableCookie cookie) {
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		try {
			ObjectOutputStream outputStream = new ObjectOutputStream(os);
			outputStream.writeObject(cookie);
		} catch (Throwable e) {
			return null;
		}

		return byteArrayToHexString(os.toByteArray());
	}

	protected Cookie decodeCookie(String cookieStr) {
		byte[] bytes = hexStringToByteArray(cookieStr);
		ByteArrayInputStream is = new ByteArrayInputStream(bytes);
		Cookie cookie = null;
		try {
			ObjectInputStream ois = new ObjectInputStream(is);
			cookie = ((SerializableCookie) ois.readObject()).getCookie();
		} catch (Throwable e) {
			LogUtils.e(e.getMessage(), e);
		}

		return cookie;
	}

	// Using some super basic byte array <-> hex conversions so we don't have
	// to rely on any large Base64 libraries. Can be overridden if you like!
	protected String byteArrayToHexString(byte[] b) {
		StringBuffer sb = new StringBuffer(b.length * 2);
		for (byte element : b) {
			int v = element & 0xff;
			if (v < 16) {
				sb.append('0');
			}
			sb.append(Integer.toHexString(v));
		}
		return sb.toString().toUpperCase();
	}

	protected byte[] hexStringToByteArray(String s) {
		int len = s.length();
		byte[] data = new byte[len / 2];
		for (int i = 0; i < len; i += 2) {
			data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character
					.digit(s.charAt(i + 1), 16));
		}
		return data;
	}

	public class SerializableCookie implements Serializable {
		private static final long serialVersionUID = 6374381828722046732L;

		private transient final Cookie cookie;
		private transient BasicClientCookie clientCookie;

		public SerializableCookie(Cookie cookie) {
			this.cookie = cookie;
		}

		public Cookie getCookie() {
			Cookie bestCookie = cookie;
			if (clientCookie != null) {
				bestCookie = clientCookie;
			}
			return bestCookie;
		}

		private void writeObject(ObjectOutputStream out) throws IOException {
			out.writeObject(cookie.getName());
			out.writeObject(cookie.getValue());
			out.writeObject(cookie.getComment());
			out.writeObject(cookie.getDomain());
			out.writeObject(cookie.getExpiryDate());
			out.writeObject(cookie.getPath());
			out.writeInt(cookie.getVersion());
			out.writeBoolean(cookie.isSecure());
		}

		private void readObject(ObjectInputStream in) throws IOException,
				ClassNotFoundException {
			String name = (String) in.readObject();
			String value = (String) in.readObject();
			clientCookie = new BasicClientCookie(name, value);
			clientCookie.setComment((String) in.readObject());
			clientCookie.setDomain((String) in.readObject());
			clientCookie.setExpiryDate((Date) in.readObject());
			clientCookie.setPath((String) in.readObject());
			clientCookie.setVersion(in.readInt());
			clientCookie.setSecure(in.readBoolean());
		}
	}
}

以上就是如何使登录态持久化,希望对大家有用。






  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要使用xUtils框架进行GET请求,你需要进行以下步骤: 1. 添加xUtils依赖 在项目的build.gradle文件中添加xUtils的依赖: ```groovy dependencies { // 其他依赖... implementation 'org.xutils:xutils:3.7.7' } ``` 2. 发起GET请求 使用xUtils的HttpUtils类可以方便地发起GET请求。下面是一个示例代码: ```java import org.xutils.common.Callback; import org.xutils.http.RequestParams; import org.xutils.x; // 创建请求参数对象 RequestParams params = new RequestParams("http://www.example.com/api"); // 设置请求参数(可选) params.addQueryStringParameter("key1", "value1"); params.addQueryStringParameter("key2", "value2"); // 发起GET请求 x.http().get(params, new Callback.CommonCallback<String>() { @Override public void onSuccess(String result) { // 请求成功回调,result为响应结果 } @Override public void onError(Throwable ex, boolean isOnCallback) { // 请求错误回调 } @Override public void onCancelled(CancelledException cex) { // 请求取消回调 } @Override public void onFinished() { // 请求完成回调,无论成功或失败都会调用 } }); ``` 在示例代码中,我们首先创建了一个RequestParams对象,并指定了请求的URL。然后,我们可以使用addQueryStringParameter()方法添加请求参数(可选)。最后,通过调用x.http().get()方法发起GET请求,并传入回调对象。 回调对象是一个实现了Callback接口的匿名内部类,通过重写相应的方法来处理请求的结果。onSuccess()方法在请求成功时被调用,onError()方法在请求错误时被调用,onCancelled()方法在请求被取消时被调用,onFinished()方法在请求完成时被调用。 你可以根据自己的需求对回调方法进行相应的处理和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值