• QQ
  • nahooten@sina.com
  • 常州市九洲新世界花苑15-2

Android

Android Service_AlarmManager组合坑

原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/Android/2019/0801/589.html

Android Service,AlarmManager组合完成按时使命踩的坑
 
做名目时碰到一个场景:app必要按时走访背景,感知获取登录用户有无非常新的消息。
 
我常州手游开发接纳了定义一个Service,在onStartCo妹妹and()要领中要求背景获取非常新消息,接着建立一个AlarmManager来延时发送播送,再定义一个播送汲取器,汲取到一个播送后,汲取器触发startService( ),这时service的onStartCo妹妹and再次被触发,就再次要求获取非常新消息,继续发送播送,云云来去。
 
用户名userId是登录胜利后就能得到的。在登录胜利进入主界面后,并登时启动MyNewTaskService
 
MyNewTaskService的要紧常州游戏开发培训交易逻辑代码以下:
 
    public int onStartCo妹妹and(Intent intent, int flags, int startId) {
        mRealm = Realm.getDefaultInstance();
        mUserDao = new UserDao(mRealm);//获取目前登录用户id
        mTaskTimeDao = new TaskTimeDao(mRealm);        if(intent!=null){
            userId = intent.getStringExtra("userId");
        }else{
            userId = mUserDao.getUserInfo().getUserId();//realm也留存了用户信息,但不必然每次都能获取到
        }        if(null!=userId){            //...做少许工作,好比走访网页获取非常新消息
            //设置按时操纵
            AlarmManager am= (AlarmManager)getSystemService(ALARM_SERVICE);            //1分钟要求一次更新
            int elapseTime = 1*60*1000;            long interval = SystemClock.elapsedRealtime()+elapseTime;            //传递userId参数给MyNewTaskReceiver,为了到时候回传回归
            Intent i = new Intent(this,MyNewTaskReceiver.class);
            i.putExtra("userId",userId);
            PendingIntent pi = PendingIntent.getBroadcast(this,0,i,0);
            am.set(AlarmManager.ELAPSED_REALTIME,interval,pi);
        }        return super.onStartCo妹妹and(intent, flags, startId);
    }
 
底下是MyNewTaskReceiver类
 
public class MyNewTaskReceiver extends BroadcastReceiver{    
    @Override
    public void onReceive(Context context, Intent intent) {
        Intent i= new Intent(context, MyNewTaskService.class);
        i.putExtra("userId",intent.getStringExtra("userId"));
        Log.i("user",intent.getStringExtra("userId"));
        context.startService(i);        //每1分钟将汲取到一次播送,这时触发service的onStartCo妹妹and()实行必要的重复操纵
    }
}
 
不过手机App外包app测试时发现,当第一次登录进入后,例云云时用户名是 ‘zs’ ,这是背景能够每1分钟汲取到’zs’的非常新的消息。不过,现在’zs’退出登录,用’ls’账号登录,这时背景回笼的消息仍旧照旧’zs’的,而不是’ls’的。
 
后来发现,每顺次一个登录的用户登岸后,背面无论任何其余用户再次登录同一台手机,背景回笼的都是第一个用户的信息。由于App计划的时第一次登录胜利后,Service会一直在背景实行。以是质疑第一次建立Service后,Service所持有的userId并无更新。
 
经由调试,发现,MyNewTaskReceiver汲取的Intent中获取的userId全都是第一次登录用户的id。料想可能发送播送时传入的参数有问题。
 
经由查阅安卓API发现,按时器AlarmManager初始化时传入的PendingIntent的组织函数的第四个参数必要一个Flag常量。 
这里写图片描述
 
之前我传入的是0。没有感化。
 
当改成 FLAG_UPDATE_CURRENT 时,每次发送的播送传递的Intent就能更新了。 
这里写图片描述
 
将onStartCo妹妹and()要领的这一行改成
 
 PendingIntent pi = PendingIntent.getBroadcast(this,0,i,0);
1
PendingIntent pi = PendingIntent.getBroadcast(this,0,i,FLAG_UPDATE_CURRENT);
1
这时无论那个用户登录,背景都能够按时回笼目前用户的消息了。
 
总结&留意:
 
1 该示例的背景Service在用户封闭app后并无stop。要是stop,相信不会有这种Bug发生。由于按时使命是倚赖于Service存在的。
 
2 已经是测试在主Activity的onDestory()中挪用StopService()要领让app封闭后service也结束运行,没有胜利。要是service在app封闭后也休止运行,相信不会有这种bug发生。
 
3 app经由多方面测试才能完善。
 

上篇:上一篇:AndroidStudio异常drawable context
下篇:下一篇:SQLite数据库存储(建、增、改、删查)