尊重他人的劳动成果,转载请标明出处:http://blog.csdn.net/gengqiquan/article/details/51881692, 本文出自:【gengqiquan的博客】
看完这篇博客你可以做到需要登录的操作只需要如下一句代码
LoginUtil.checkLogin(mContext, () -> // do something need login);
绝大部分app中都会有登录功能,许多操作在进行前我们需要去判断用户是否登录,已登录的情况下才允许继续去执行操作。
一般有以下两种情况
1.判断是否登录。已登录直接执行操作。没有登录跳转登录界面,用户操作后返回之前界面,此时需要再次进行判断是否已经完成了登录(用户可能直接直接返回或者取消登录操作),如果登录成功了就执行操作,没有就什么都不做
2。判断是否登录,已登录直接执行操作,没有登录跳转登录界面,用户操作后返回之前界面,此时不做任何操作。用户需要再次手动再次进行之前的点击操作。
今天我们来通过一种比较好的方式实现第一种情况的登录验证。第二种情况体验的角度来说不够好,当然如果产品要求也可以实现,大家可以参考代码进行改动。
首先我们需要有一个登录凭证,这个凭证应该是具有唯一性的,服务端返回的,一般视服务端架构情况而定,有的是token,有的是手机号,那么我们就得先定义一个全局的静态变量,这里我们把他放在配置类里,因为许多情况下,用户的登录状态是需要长期保存的,这样我们就可以在应用初始的时候读写配置,将登陆凭证读取到这个全局变量里,代码如下
定义全局配置变量
public class Configure {
public static String USERID = "";
}
在应用初始,例如启动Activity里获取本地保存的登录配置和用户信息
// 初始化
public static void init(Context mContext) {
Configure.USERID = SharedUtil.getString(mContext, "USERID");
if ( !Util.checkNULL(Configure.USERID))
getUserInfo();
}
定义一个登录判断工具类
public class LoginUtil {
public static void checkLogin(Context context,LoginForCallBack callBack) {
// 弱引用,防止内存泄露,
WeakReference<Context> reference= new WeakReference<Context>(context);
if (Util.checkNULL(Configure.SIGNID)) { // 判断是否登录,否返回true
Configure.CALLBACK = new ICallBack() {
@Override
public void postExec() {
// 登录回调后执行登录回调前需要做的操作
if (!Util.checkNULL(Configure.SIGNID)) {
// 这里需要再次判断是否登录,防止用户取消登录,取消则不执行登录成功需要执行的回调操作
callBack.callBack();
//防止调用界面的回调方法中有传进上下文的引用导致内存泄漏
Configure.CALLBACK = null;
}
}
};
Context mContext = reference.get();
if (mContext != null) {
Intent intent = new Intent(mContext, LoginAcitvity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
reference=null;
}
} else {
// 登录状态直接执行登录回调前需要做的操作
callBack.callBack();
}
}
public void clear() {
try {
finalize();
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 声明一个登录成功回调的接口
public interface ICallBack {
// 在登录操作及信息获取完成后调用这个方法来执行登录回调需要做的操作
void postExec();
}
@FunctionalInterface//Java8 函数注解,没有升级java8的去掉这一句
public interface LoginForCallBack {
void callBack();
}
}
上面我们可以看到有个ICallBack接口。这个接口是要在登录界面里 进行调用的为了方便我们定义一个全局的接口变量,同样放在配置类里
public class Configure {
public static String USERID = "";
// 登录回调接口
public static ICallBack CALLBACK;
}
在登录页面LoginActivity里的登录成功回调方法里进行全局登录凭证的赋值和本地持久化
Configure.USERID = obj.getString("memberId");
if (Configure.USERID != null ) {
SharedUtil.putString(mContext, "USERID", Configure.USERID);
}
在LoginActivity的onDestroy()调用我我们之前的全局回调变量的回调方法
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
if (Configure.CALLBACK != null)
Configure.CALLBACK.postExec();
}
在我们需要进行登陆判断的操作的地方调用
LoginUtil.checkLogin(mContext, new LoginUtil.LoginForCallBack() {
@Override
public void callBack() {
// do somethisgs
}
});
如果支持Java8则这样调用
LoginUtil.checkLogin(mContext, () -> {
// do somethings
});
or
LoginUtil.checkLogin(mContext, () -> // do something );
怎么样,是不是很简单简洁,不需要再写那么多的activityresult方法,也不需要每次去判断返回后到底有没有登录
代码比较少,就没有单独抽取成工程,有什么地方有疑问或者建议的可以留言。
我建了一个QQ群(群号:121606151),用于大家讨论交流Android技术问题,有兴趣的可以加下,大家一起进步。