Android开源中国客户端学习 消息模块
2013-07-22 21:31
375 查看
今天学习一下osc客户端的消息模块主要使用了动态receiver注册和静态注册,具体的功能有:
1.获取用户新的动态 并弹出notification显示 如果app在前台还要更新UI显示
2.发送完动弹后的UI通知更新机制
3.当前list内容有更新时候的Toast通知
其实3 并不能算是真正的消息机制,但是这里还是并入这个模块分析
1.新动态的消息机制
osc的获取动态通知的实现比较简单,是轮询.当然,对于osc这样的实时性不是很强应用来说使用http轮询就可以了,不必使用一些xmpp什么的增加成本
在app启动的时候会使用foreachUserNotice()函数来启动轮询
代码很简单,就是通过递归的方式 , 每隔60秒 想服务器请求一次notice ,网络的数据也是xml的这里就不分析了.
这样有个小问题
这个receiver是在xml中静态注册的
BroadCast.java这个Receiver的代码就不贴了 主要做两件事:
a更新应用中各个 气泡的消息数量
b弹出notification
在更新了list后 还会调用main中的ClearNotice()成员函数 通知服务器更新未读消息列表,这个不再赘述
2.发送动弹后的消息更新机制
发送动弹后,pub 的activity会发送一个消息给main ,main会有一些几个行为
a发送成功,返回main并更新
b发送失败,dialog提示用户重新发送,如果还是失败,那么提示用户网络错误
其实个人感觉这个行为应该直接由tweetpub来处理而不应该通过消息机制让main来处理,main只需要知道是否发送成功就可以了,但是这里还是分析一下动态注册receiver的使用:
在应用打开的时候调用首先会动态注册一个Receiver
在tweetpub中 发送了动弹之后会执行:
ok 这样Main的内部类 TweetReceiver的onReceive函数可以被回调了:
如果成功就自己更新UI 这里请自行看代码
如果失败就会初始化一个thread和一个handler然后重新启动刚刚初始化的那个发送动弹的线程:
然后在handler中进行发送结果的处理:
主要:
发送成功:更新UI
发送失败:progressdialog dismisse掉然后提示用户发送失败.
3.当前list内容有更新时候的Toast通知
这是一个小知识点,其实应该在第一章介绍的.功能如图所示:
这个是在handler中调用handleLvData()函数的时候触发的,代码:
原理是自定义了一个Toast,虽然很简单,但是用户交互很好:
声明:eoe文章著作权属于作者,受法律保护,转载时请务必以超链接形式附带如下信息
原文作者: sfshine
原文地址: http://my.eoe.cn/sfshine/archive/5823.html
1.获取用户新的动态 并弹出notification显示 如果app在前台还要更新UI显示
2.发送完动弹后的UI通知更新机制
3.当前list内容有更新时候的Toast通知
其实3 并不能算是真正的消息机制,但是这里还是并入这个模块分析
1.新动态的消息机制
osc的获取动态通知的实现比较简单,是轮询.当然,对于osc这样的实时性不是很强应用来说使用http轮询就可以了,不必使用一些xmpp什么的增加成本
在app启动的时候会使用foreachUserNotice()函数来启动轮询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | /** * 轮询通知信息 */ private void foreachUserNotice() { final int uid = appContext.getLoginUid(); final Handler handler = new Handler() { public void handleMessage(Message msg) { if (msg.what == 1) { UIHelper.sendBroadCast(Main.this, (Notice) msg.obj); } foreachUserNotice();// 回调 } }; new Thread() { public void run() { Message msg = new Message(); try { sleep(60 * 1000); if (uid > 0) { Notice notice = appContext.getUserNotice(uid); msg.what = 1; msg.obj = notice; } else { msg.what = 0; } } catch (AppException e) { e.printStackTrace(); msg.what = -1; } catch (Exception e) { e.printStackTrace(); msg.what = -1; } handler.sendMessage(msg); } }.start(); } |
这样有个小问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | Message msg = new Message(); 这句话最好用hander.obtaiMessage() 或者 Message msg = Message.obtain(); 来获取Message 这样可以节约资源浪费 如果有消息更新 就发送广播,这个就是就比较简单了sendBroadCast函数在UIHelper中: public static void sendBroadCast(Context context, Notice notice) { if (!((AppContext) context.getApplicationContext()).isLogin() || notice == null) return; Intent intent = new Intent("net.oschina.app.action.APPWIDGET_UPDATE"); intent.putExtra("atmeCount", notice.getAtmeCount()); intent.putExtra("msgCount", notice.getMsgCount()); intent.putExtra("reviewCount", notice.getReviewCount()); intent.putExtra("newFansCount", notice.getNewFansCount()); context.sendBroadcast(intent); } |
1 2 3 4 5 | <receiver android:name=".ui.BroadCast"> <intent-filter> <action android:name="net.oschina.app.action.APPWIDGET_UPDATE" /> </intent-filter> </receiver> |
a更新应用中各个 气泡的消息数量
b弹出notification
在更新了list后 还会调用main中的ClearNotice()成员函数 通知服务器更新未读消息列表,这个不再赘述
2.发送动弹后的消息更新机制
发送动弹后,pub 的activity会发送一个消息给main ,main会有一些几个行为
a发送成功,返回main并更新
b发送失败,dialog提示用户重新发送,如果还是失败,那么提示用户网络错误
其实个人感觉这个行为应该直接由tweetpub来处理而不应该通过消息机制让main来处理,main只需要知道是否发送成功就可以了,但是这里还是分析一下动态注册receiver的使用:
在应用打开的时候调用首先会动态注册一个Receiver
1 2 3 4 5 | // 注册广播接收器 tweetReceiver = new TweetReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction("net.oschina.app.action.APP_TWEETPUB"); registerReceiver(tweetReceiver, filter); |
1 | UIHelper.sendBroadCastTweet(TweetPub.this, what, res, tweet); |
1 2 3 4 5 | public static void sendBroadCastTweet(Context context, int what, Result res, Tweet tweet) { if (res == null && tweet == null) return; Intent intent = new Intent("net.oschina.app.action.APP_TWEETPUB"); intent.putExtra("MSG_WHAT", what); if (what == 1) intent.putExtra("RESULT", res); else intent.putExtra("TWEET", tweet); context.sendBroadcast(intent); } |
如果成功就自己更新UI 这里请自行看代码
如果失败就会初始化一个thread和一个handler然后重新启动刚刚初始化的那个发送动弹的线程:
1 2 3 4 | if (TweetPub.mContext != null) UIHelper.showResendTweetDialog(TweetPub.mContext, thread); else UIHelper.showResendTweetDialog(context, thread); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | final Handler handler = new Handler() { public void handleMessage(Message msg) { if (msg.what == 1) { Result res = (Result) msg.obj; UIHelper.ToastMessage(context,res.getErrorMessage(), 1000); if (res.OK()) { // 发送通知广播 if (res.getNotice() != null) { UIHelper.sendBroadCast(context,res.getNotice()); } // 发完动弹后-刷新最新、我的动弹&最新动态 if (curTweetCatalog >= 0 && mCurSel == 2) { loadLvTweetData(curTweetCatalog, 0,lvTweetHandler,UIHelper.LISTVIEW_ACTION_REFRESH); } else if (curActiveCatalog == ActiveList.CATALOG_LASTEST&& mCurSel == 3) { loadLvActiveData(curActiveCatalog, 0,lvActiveHandler,UIHelper.LISTVIEW_ACTION_REFRESH); } if (TweetPub.mContext != null) { // 清除动弹保存的临时编辑内容 appContext.removeProperty(AppConfig.TEMP_TWEET,AppConfig.TEMP_TWEET_IMAGE); ((Activity) TweetPub.mContext).finish(); } } } else { ((AppException) msg.obj).makeToast(context); if (TweetPub.mContext != null&&TweetPub.mMessage != null) TweetPub.mMessage.setVisibility(View.GONE); } } }; |
发送成功:更新UI
发送失败:progressdialog dismisse掉然后提示用户发送失败.
3.当前list内容有更新时候的Toast通知
这是一个小知识点,其实应该在第一章介绍的.功能如图所示:
这个是在handler中调用handleLvData()函数的时候触发的,代码:
1 2 3 4 5 | NewDataToast .makeText( this, getString(R.string.new_data_toast_message, newdata), appContext.isAppSound()) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | /** * 新数据Toast提示控件(带音乐播放) * @author liux (http://my.oschina.net/liux) * @version 1.0 * @created 2012-8-30 */ public class NewDataToast extends Toast{ private MediaPlayer mPlayer; private boolean isSound; public NewDataToast(Context context) { this(context, false); } public NewDataToast(Context context, boolean isSound) { super(context); this.isSound = isSound; mPlayer = MediaPlayer.create(context, R.raw.newdatatoast); mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){ @Override public void onCompletion(MediaPlayer mp) { mp.release(); } }); } @Override public void show() { super.show(); if(isSound){ mPlayer.start(); } } /** * 设置是否播放声音 */ public void setIsSound(boolean isSound) { this.isSound = isSound; } /** * 获取控件实例 * @param context * @param text 提示消息 * @param isSound 是否播放声音 * @return */ public static NewDataToast makeText(Context context, CharSequence text, boolean isSound) { NewDataToast result = new NewDataToast(context, isSound); LayoutInflater inflate = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); DisplayMetrics dm = context.getResources().getDisplayMetrics(); View v = inflate.inflate(R.layout.new_data_toast, null); v.setMinimumWidth(dm.widthPixels);//设置控件最小宽度为手机屏幕宽度 TextView tv = (TextView)v.findViewById(R.id.new_data_toast_message); tv.setText(text); result.setView(v); result.setDuration(600); result.setGravity(Gravity.TOP, 0, (int)(dm.density*75)); return result; } } |
原文作者: sfshine
原文地址: http://my.eoe.cn/sfshine/archive/5823.html
相关文章推荐
- Android开源中国客户端学习 截屏模块
- Android开源中国客户端学习 微博分享模块 <8>
- Android开源中国客户端学习 异步加载图片
- Android开源中国客户端学习 (自定义View)左右滑动控件ScrollLayout
- OSCHINA Android 客户端 - 手机相关软件 - 开源中国
- 学习开源中国客户端
- 开源中国iOS客户端学习——(三)再看协议与委托
- Android开源客户端之LookAround学习(三) 界面框架
- 开源中国源码学习数据篇(一)之android-async-http框架和AsyncTask
- 开源中国 OsChina Android 客户端源码分析(11)缓存对象
- 开源中国 OsChina Android 客户端源码分析(2)滑动菜单DrawerLayout
- Android开源客户端之LookAround学习(一)Application & 网络框架
- Android开源客户端之LookAround学习(二) 图片异步加载
- 【开源中国Android客户端】源码分析(一) 启动
- Android开源客户端之LookAround学习(四) 收尾
- Android(java)学习笔记206:利用开源SmartImageView优化网易新闻RSS客户端
- 开源中国客户端源码学习
- 开源中国iOS客户端学习——(七)MBProgressHUD特效
- 开源中国iOS客户端学习——(八)网络通信AFNetworking类库
- 学习Android开源项目-根据知乎日报API分析重构一个简单的知乎日报Android客户端