android Service+EventBus实现异地登录提示

我是用retrofit做的网络接口,当异地登录时,errorbody信息是固定数据(不能用公司的,随便换个等效的)

{"error_state":1,"error_msg":"异地登录"}

然后我想是每个activity都有可能弹出数据,那么怎么保证每个都会弹出呢?难道每个接口都写一次?太麻烦了。。。。
于是:在返回数据进行处理:

if(response.code()!=200 && response.errorbody()!=null){
    ErrorData data = new ErrorData();
    if(data.getError_state() == 1){
        EventBus.getDefault().post(new ShowLogoutDialog());
    }
}

然后想用service处理,但service里面没有activity的引用,系统对话框又另外需要权限怎么办呢?
于是在baseactivity获取焦点的时候就更新service里面的context:

 private boolean isFirst = true;
    @Override
    public final void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus && isFirst) {
            isFirst = false;
            EventBus.getDefault().post(this);
        }
    }
public class MyService extends Service {
    public class MyBinder extends Binder {

        public MyService getService(){
            return MyService .this;
        }
    }

    private WeakReference weakContext;

    private MyBinder binder = new MyBinder();

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent,flags,startId);
    }

    @Override
    public IBinder onBind(Intent intent) {
        EventBus.getDefault().register(this);
        return binder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        EventBus.getDefault().unregister(this);
        return false;
    }

    private HintDialog dialog;
    @Subscribe
    public void showExitDialog(ShowLogoutDialog event){
        if(weakContext == null || weakContext.get() == null)
            return;
        if(dialog == null){
            dialog = new HintDialog(weakContext.get())
                    .setMessage("检测到当前账号在其他设备登录,请重新登录!")
                    .setPositiveName("确定")
                    .setPositiveListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            //关闭所有activity
                            EventBus.getDefault().post(new CloseAllActivity());
                            Intent intent = new Intent(MyService.this, LoginActivity.class);
                            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            //设置登录状态为false...这一步不写了,读者怎么设的怎么写
                            startActivity(intent);
                            stopSelf();//这句一定要,因为登录页到主页又会启动服务
                        }
                    });
            dialog.setCancelable(false);
        }

        dialog.show();
    }

    @Subscribe
    public void updateContext(Context context){
        weakContext = new WeakReference<>(context);
    }
}

总结:
原理:
1.在主页注册oncreate注册service,当启动新页面或旧页面重新启用时,通过EventBus,service自动更新当前context,为了防止内存泄漏,所以用了weakReferences进行context保存。

2.进行网络请求时,错误如果是异地登录,则要求service弹出dialog,因为之前EventBus设置的context已经是当前的context,所以service能够根据网络请求的post正确弹出当前页面dialog而不用使用系统对话框
3.对于这种每个页面都要用的东西,采用公共服务类可以更加方便

ps:
在此期间,还做过一个网络请求到来时的等待框,但是最终没有放到service中,因为下拉刷新时,已经有了等待的提示,无需另外弹出提示,网络请求到来的提示可能会有多种,直接固定死将来也会有隐患。当然也可以根据不同的callback实现不同种类的请求,从而实现显示和不显示提示两种效果,这一点留给读者去思考。

你可能感兴趣的:(归纳整理)