Oschina 安卓用戶端源碼學習之三,oschina安卓
今天呢,來研究一個功能,訊息通知
(1)首先是訊息推送的獲得或者說是產生。
在main.java這個檔案裡有這樣一個函數
/** * 輪詢通知資訊 */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();}
這便是簡單粗暴的訊息取得過程
sleep(60* 1000);
休息一分鐘之後appContext.getUserNotice(uid);通過這個函數來取得訊息。跟蹤該函數代碼後得知,它其實是和開源中國的伺服器請求了一些資料,然後構造成Notice對象,返回來。然後塞到msg裡。最後通過handler.sendMessage(msg);把msg發送出去。而在上面handleMessage裡頭又調用了foreachUserNotice()這個函數。這就是最終的一個過程,周而復始,一分鐘歇一次,歇夠了要資料。專業一點叫輪詢。
然後我們看這個handleMessage裡頭有一個sendBroadCast函數,也就是說輪詢之後得到的notice最終都是發送廣播,發送出去了。
(2)接下來,我們來看看廣播的接收部分
首先靜態註冊了一個廣播
<receiver android:name=".ui.BroadCast"> <intent-filter> <action android:name="net.oschina.app.action.APPWIDGET_UPDATE"/> </intent-filter> </receiver>
我們找到ui.BroadCast這個類,下面是對收到的廣播的處理方法
@Override public void onReceive(Contextcontext, Intent intent) { StringACTION_NAME = intent.getAction(); if("net.oschina.app.action.APPWIDGET_UPDATE".equals(ACTION_NAME)) { int atmeCount =intent.getIntExtra("atmeCount", 0);//@我 int msgCount =intent.getIntExtra("msgCount", 0);//留言 int reviewCount =intent.getIntExtra("reviewCount", 0);//評論 int newFansCount =intent.getIntExtra("newFansCount", 0);//新粉絲 int activeCount = atmeCount+ reviewCount + msgCount + newFansCount;//資訊總數 //動態-總數 if(Main.bv_active != null){ if(activeCount > 0){ Main.bv_active.setText(activeCount+""); Main.bv_active.show(); }else{ Main.bv_active.setText(""); Main.bv_active.hide(); } } //@我 if(Main.bv_atme != null){ if(atmeCount > 0){ Main.bv_atme.setText(atmeCount+""); Main.bv_atme.show(); }else{ Main.bv_atme.setText(""); Main.bv_atme.hide(); } } //評論 if(Main.bv_review != null){ if(reviewCount > 0){ Main.bv_review.setText(reviewCount+""); Main.bv_review.show(); }else{ Main.bv_review.setText(""); Main.bv_review.hide(); } } //留言 if(Main.bv_message != null){ if(msgCount > 0){ Main.bv_message.setText(msgCount+""); Main.bv_message.show(); }else{ Main.bv_message.setText(""); Main.bv_message.hide(); } } //通知欄顯示 this.notification(context,activeCount); } }
查看代碼得知bv_active等bv開頭的變數類型都是BadgeView變數。這個類繼承自textView類。實現的功能呢就是一個控制項上方一個紅色小圓圈,裡面有數字。也就是說提示你的新訊息條數,這玩意,很常用的哈。具體的就不說了。
這裡呢就是把notice的內容拿出來去更新這個控制項。這個訊息的過程在這就走到終點了。
this.notification這個函數呢,很明顯就是手機通知欄的訊息通知了
咱們來看看
private voidnotification(Context context, int noticeCount){ //建立NotificationManager NotificationManagernotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); StringcontentTitle = "開源中國"; StringcontentText = "您有 " + noticeCount + " 條最新資訊"; int _lastNoticeCount; //判斷是否發出通知資訊 if(noticeCount == 0) { notificationManager.cancelAll(); lastNoticeCount= 0; return; } else if(noticeCount == lastNoticeCount) { return; } else { _lastNoticeCount= lastNoticeCount; lastNoticeCount= noticeCount; } //建立通知 Notification Notificationnotification = null; if(noticeCount >_lastNoticeCount) { StringnoticeTitle = "您有 " + (noticeCount-_lastNoticeCount) + " 條最新資訊"; notification= newNotification(R.drawable.icon, noticeTitle, System.currentTimeMillis()); } else { notification= newNotification(); } //設定點擊通知跳轉 Intentintent = newIntent(context, Main.class); intent.putExtra("NOTICE",true); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntentcontentIntent = PendingIntent.getActivity(context, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT); //設定最新資訊 notification.setLatestEventInfo(context,contentTitle, contentText, contentIntent); //設定點擊清除通知 notification.flags = Notification.FLAG_AUTO_CANCEL; if(noticeCount >_lastNoticeCount) { //設定通知方式 notification.defaults |= Notification.DEFAULT_LIGHTS; //設定通知音-根據app設定是否發出提示音 if(((AppContext)context.getApplicationContext()).isAppSound()) notification.sound = Uri.parse("android.resource://"+ context.getPackageName() + "/" + R.raw.notificationsound); //設定震動 <需要加上使用者權限android.permission.VIBRATE> //notification.vibrate = new long[]{100, 250, 100, 500}; } //發出通知 notificationManager.notify(NOTIFICATION_ID,notification); }
具體的就不分析了,還是很簡單的。
android系統源碼
使用 Git 擷取 Android 源碼的方法:
android.googlesource.com/mirror/manifest.git
擷取 Android 源碼的方法:
mkdir /usr/local/android-mirror cd /usr/local/android-mirror repo init --mirror -u android.googlesource.com/mirror/manifest repo sync mkdir /usr/local/android-2.3.7 cd /usr/local/android-2.3.7 repo init -u /usr/local/mirror/platform/manifest.git -b android-2.3.7_r1 repo sync repo init -u android.googlesource.com/platform/manifest repo sync
android系統是開源的,系統代碼都可以看到,那軟體的原始碼會被看到?
一樓2貨啊
二樓三樓正解,系統軟體也是開源的,但是第三方開發的軟體不一定會給你開源