国际惯例,先上效果图
首先,对于监听账号是否在其他设备登录的方法,我们一般都会使用第三方即时通讯自带的监听功能,优点就是代码简单,可以实时监听。没有集成第三方即时通讯的,就得用代码自己实现了,当然这不是我们今天的重点,不再讨论。
当我们的账号在其他设备登录时,无论我们当前在哪个界面都需要弹出提示框,提醒用户,所以弹出对话框的逻辑我们需要写在Activity的基类中。
当用户选择取消的时候,需要退出当前应用,或者退出登录状态;当用户选择重新登录的话,则跳到登录界面,重新登录。
在基类中,我们需要创建需要子类实现的抽象方法
public abstract class BaseActivity extends AppCompatActivity {
private static LinkedList activities;//用户存储每一个打开的Activity
private RelativeLayout container;//用户存放样式
private Unbinder mButterBind;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (activities == null) {
activities = new LinkedList<>();
}
activities.add(this); //将当前activity放入到列表中
container = new RelativeLayout(this);
container.addView(LayoutInflater.from(this).inflate(initLayout(), null, false), new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
setContentView(container, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
mButterBind = ButterKnife.bind(this);
initView();
initData();
bindListener();
}
protected abstract int initLayout();//子类在此方法中设置其布局样式
protected abstract void initView(); //初始化子类view
protected abstract void initData(); //初始化子类数据
protected abstract void bindListener();//存放子类的点击事件
@Override
protected void onDestroy() {
super.onDestroy();
//当activity中退出时,将其从列表中移除
if (activities != null) {
activities.remove(this);
}
mButterBind.unbind();
}
}
在基类中,我们可以抽取一个常用的方法
/**
* 彻底退出app
*/
protected void exitApp() {
//需要退出app时,调用此方法
for (AppCompatActivity baseActivity : activities) {
baseActivity.finish();
}
activities.clear();//养成良好的习惯,不用的数据,需要及时清空,减少应用内存
activities = null;
}
/**
* 跳转到指定的页面
*
* @param clazz
*/
public void startActivity(Class clazz) {
Intent intent = new Intent(this, clazz);
startActivity(intent);
}
这样,我们一个简单的activity的基类就基本上写好了。
首先,当我们监听到账号在其他设备登录时,我们需要通知当前的应用,弹出提示对话框,一般来说,我们都是发广播。
@OnClick(R.id.show)
public void onClick() {
//我们假装我们点击按钮的时候就是我们监听到账号在其他设备登录的时候,收到监听立即发送广播
Intent intent = new Intent();
intent.setAction("LoginOut");
sendBroadcast(intent);
}
而在BaseActivity中,我们需要注册广播接收者,接受其他设备登录的消息
//注册广播
receiver = new OtherEquipmentLoginReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("LoginOut");
registerReceiver(receiver, intentFilter);
当然,也别忘了注销广播接收者
@Override
protected void onDestroy() {
super.onDestroy();
if (activities != null) {
activities.remove(this);
}
//解除广播
unregisterReceiver(receiver);
mButterBind.unbind();
}
当我们接收到广播的时候,立即对用户弹出提示对话框
/**
* 在其他设备登录
*/
public class OtherEquipmentLoginReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
if("LoginOut".equals(intent.getAction())){
otherEquipmentLogin();
}
}
}
private void otherEquipmentLogin() {
final CommonDialog otherLoginDialog = new CommonDialog(BaseActivity.this);
otherLoginDialog.setContent("您的账号已在其他设备登录,请重新登录!");
otherLoginDialog.setTitle("警告");
otherLoginDialog.setEnsure("重新登录");
otherLoginDialog.setCancelable(false);
otherLoginDialog.setCanceledOnTouchOutside(false);
otherLoginDialog.setOnEnsureClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//点击重新登录,跳转到登录界面
startActivity(LoginActivity.class);
otherLoginDialog.dismiss();
}
});
otherLoginDialog.setOnCancelClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//点击取消退出app
exitApp();//杀死所有已创建的activity,退出应用
otherLoginDialog.dismiss();
}
});
otherLoginDialog.show();
}
所以,我们需要加判断!
我们在每次创建一个activity时,都会把该Activity加入到一个存放activity的列表中。而由于每个压在下面的activity都没有销毁,所以对他们来说。列表中存放的最后一个activity即是它们本身。所以我们可以这样判断
private void otherEquipmentLogin() {
//如果列表中的最后一个activity 跟当前activity相同时,则可以弹出对话框
if(activities.getLast().getClass()==this.getClass()){
final CommonDialog otherLoginDialog = new CommonDialog(BaseActivity.this);
otherLoginDialog.setContent("您的账号已在其他设备登录,请重新登录!");
otherLoginDialog.setTitle("警告");
otherLoginDialog.setEnsure("重新登录");
otherLoginDialog.setCancelable(false);
otherLoginDialog.setCanceledOnTouchOutside(false);
otherLoginDialog.setOnEnsureClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//跳转到登录界面
startActivity(LoginActivity.class);
otherLoginDialog.dismiss();
}
});
otherLoginDialog.setOnCancelClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//点击取消退出app
exitApp();
otherLoginDialog.dismiss();
}
});
otherLoginDialog.show();
}
}
代码在这里