【oschina android源码分析】页面通知(站内信)的设计-android轮询方案
2016-05-21 18:29
543 查看
站内信采用的是一个android系统下常见的轮询方案。包括:
NoticeService是轮询所在的服务,自己单独一个进程。定时消息,网络请求都封装在改服务中。
NoticeUtils扮演客户端,去绑定NoticeService。
INoticeService.aidl是进程间通信的aidl文件。
AlarmReceiver。
该aidl文件的设计:
因为客户端需要调用requestNotice和clearNotice方法,所以需要在INoticeService中增加这两个方法,但是scheduleNotice客户端并不需要调用,所以这里是可以删除的,我们只需要在aidl文件中声明客户端需要调用的方法即可,不需要的可以删除。
aidl文件的设计也是非常关键的。
说明:
AlarmManager是一个android系统服务,不会受锁屏等等的影响,是比较靠谱的轮询解决方案。
说明:
因为AlarmManager必须接收一个pendingintent作为参数,所以除了广播接收者,服务之外确实没有更好的选择了,所以这里也是可以选择使用服务的,使用startService的方式,在onStartCommand方法中来实进行网络请求。
说明:
即使该广播接受者是由noticeservice所在的服务启动的,该广播接受者仍属于app的进程,所以onreceive方法仍要在app所在的进程执行,仍属于跨进程的。要跨进程去调用noticeservice中的方法,这里选择还是NoticeUtils。省去了再写一个客户端的烦恼。
说明:
需要接受消息的页面要注册广播接受者,来接受该广播。(广播可以跨进程)
NoticeService是轮询所在的服务,自己单独一个进程。定时消息,网络请求都封装在改服务中。
NoticeUtils扮演客户端,去绑定NoticeService。
INoticeService.aidl是进程间通信的aidl文件。
AlarmReceiver。
该aidl文件的设计:
interface INoticeService { void scheduleNotice(); void requestNotice();//请求网络 void clearNotice(int uid,int type);//停止请求 }
因为客户端需要调用requestNotice和clearNotice方法,所以需要在INoticeService中增加这两个方法,但是scheduleNotice客户端并不需要调用,所以这里是可以删除的,我们只需要在aidl文件中声明客户端需要调用的方法即可,不需要的可以删除。
aidl文件的设计也是非常关键的。
一.具体流程
1.使用系统服务AlarmManager来定时开启一个广播接收者。NoticeService中
// 从1秒后开始,每隔2分钟执行getOperationIntent() mAlarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 1000, INTERVAL, getOperationIntent());
说明:
AlarmManager是一个android系统服务,不会受锁屏等等的影响,是比较靠谱的轮询解决方案。
2.定时启动一个广播接收者。NoticeService
OSC采用轮询方式实现消息推送,每次被调用都去执行一次{@link #AlarmReceiver}onReceive()方法 private PendingIntent getOperationIntent() { Intent intent = new Intent(this, AlarmReceiver.class); PendingIntent operation = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); return operation; }
说明:
因为AlarmManager必须接收一个pendingintent作为参数,所以除了广播接收者,服务之外确实没有更好的选择了,所以这里也是可以选择使用服务的,使用startService的方式,在onStartCommand方法中来实进行网络请求。
3.广播接收者。
public class AlarmReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { TLog.log("onReceive ->net.oschina.app收到定时获取消息"); NoticeUtils.requestNotice(context); } }
说明:
即使该广播接受者是由noticeservice所在的服务启动的,该广播接受者仍属于app的进程,所以onreceive方法仍要在app所在的进程执行,仍属于跨进程的。要跨进程去调用noticeservice中的方法,这里选择还是NoticeUtils。省去了再写一个客户端的烦恼。
4.广播接受者调用的网络请求。NoticeUtils中
public static void requestNotice(Context context) { if (sService != null) { try { TLog.log("requestNotice..."); sService.requestNotice(); } catch (RemoteException e) { e.printStackTrace(); } } else { context.sendBroadcast(new Intent( NoticeService.INTENT_ACTION_REQUEST)); TLog.log("requestNotice,service is null"); } }
5.接收到网络请求后,会发送广播。
/** * 发送通知广播 * * @param context * @param notice */ public static void sendBroadCast(Context context, Notice notice) { if (!((AppContext) context.getApplicationContext()).isLogin() || notice == null) return; Intent intent = new Intent(Constants.INTENT_ACTION_NOTICE); Bundle bundle = new Bundle(); bundle.putSerializable("notice_bean", notice); intent.putExtras(bundle); context.sendBroadcast(intent); }
说明:
需要接受消息的页面要注册广播接受者,来接受该广播。(广播可以跨进程)
二.一些问题
三.资料参考
http://www.kymjs.com/code/2015/01/13/01相关文章推荐
- Android 编程下的 TraceView 简介及其案例实战
- 详解Android动画之Frame Animation
- 【oschina android源码分析】登陆和退出的设计
- 第一章 JAVA入门(Android历史版本续1)
- Android Reference官方描述
- 第一章 JAVA入门(Android历史版本续3)
- 第一章 JAVA入门(Android 历史版本续2)
- Android中Preference的使用以及监听事件分析(自己学习)
- Installation error: INSTALL_FAILED_CONFLICTING_PROVIDER 解决方案-Android
- android 4.2上面实现录制系统内置声音remote submix
- 图片选择------本地相册
- Android自带分享链接不需要借助第三方ShareSDK
- 自定义ImageLoader实现图片加载线程池、图片缓存
- android使用隐藏api的方法(使用被@hide的api)
- 关于android activity启动模式
- android测试有多重要!
- 我的Android进阶之旅------>RxJava学习资料汇总
- android设置控件背景透明、半透明的方法
- android之子线程中的Toast
- Android Studio使用lambda