Android語音識別技術、消息推送機制、二維碼掃描技術、NDK、JNI
一、常用數據結構:數組,堆,棧,隊列,鏈表,樹,圖,散列表
數組:把具有相同類型的若干變量按有序的形式組織起來。
堆:是一個特殊的樹形數據結構,每個結點都有一個值。一般說的堆是指二叉堆。他的最大特點就是根節點的值最小或最大,并且根節點的兩個子樹也是一個堆。
棧:只能在某一端插入和刪除的特殊線性表。按照先進后出的原則存儲數據,先進入的數據被壓入棧底,最后的數據在棧頂,需要讀數據的時候從棧頂開始彈出數據。
隊列:一種特殊的線性表,只允許在表的前端進行刪除操作,而在表的后端進行插入操作。插入端叫隊尾,刪除端叫隊頭。隊列是按照先進先出或后進先出的原則組織數據。隊列中沒有元素的時候,
成為空對列。
鏈表:是一種物理存儲單元上非連續、非順序的存儲結構,既可以表示線性結構,又可以表示非線性結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的。鏈表由一系列結點組成,結點可以在運行時動態生成。每個結點包括兩部分,一個是存儲數據元素的數據域,另一個是存儲下一個結點地址的指針。
樹:包含n(n>0)個結點的有窮集合K,在K中定義了一個關系N,N滿足以下條件。(1)有且僅有一個結點K0,對于關系N來說沒有前驅,稱K0為根節點。
(2)除K0外,K中的每個結點,對于關系N來說有且僅有一個前驅。
(3)K中各個結點,對于關系N來說可以有m個
后繼。
圖:是由結點的有窮集合V和邊的集合E組成。在圖結構中,結點稱為頂點,邊是頂點的有序偶對,若兩個頂點之間存在一條邊,就表示這兩個頂點的是相鄰關系。
散列表:如果結構中存在關鍵字和K相等的記錄,則必定在f的存儲位置上。不需比較便可直接取得查詢記錄,稱這個關系為散列函數。
二、排序思想
快速排序:它的基本思想是通過一趟掃描后,使得排序序列的長度能大幅度地減少。在冒泡排序中,一次掃描只能確保最大數值的數移到正確位置,而待排序序列的長度可能只減少1。快速排序通過一趟掃描,就能確保某個數(以它為基準點吧)的左邊各數都比它小,右邊各數都比它大。然后又用同樣的方法處理它左右兩邊的數,直到基準點的左右只有一個元素為止。
選擇排序是常用內部排序的一種,常見的實現算法有直接選擇排序算法和堆排序算法,選擇排序的基本思想是每次從待排數據中選擇第n小的數據放到排序列表的第n個位置,假如共有N個數據待排,那么經過N-1次排序后,待排數據就已經按照從小到大的順序排列了。
直接選擇排序算法的思想比較簡單:(假設數據放在一個數組a中,且數組的長度是N)
1:從a[0]-a[N-1]中選出最小的數據,然后與a[0]交換位置
2:從a[1]-a[N-1]中選出最小的數據,然后與a[1]交換位置(第1步結束后a[0]就是N個數的最小值)
冒泡排序的基本思想是相鄰兩個元素進行比較,然后交換。第一趟后最后一個數組元素是最大或最小元素,然后對前n-1個數重復如此n-1趟。
3:從a[2]-a[N-1]中選出最小的數據,然后與a[2]交換位置(第2步結束后a[1]就是N-1個數的最小值)
以此類推,N-1次排序后,待排數據就已經按照從小到大的順序排列了。
插入排序:基本思想,每次將一個待排序的數據元素,插入到前面已經排好序的數列中的適當位置,是數列依然有序;直到待排序列元素插入完為止。
堆排序:是一種樹形選擇排序,在排序過程中,將數列看成是一顆完全二叉樹的順序存儲結構,利用完全二叉樹中雙親結點和孩子結點之間的呢在關系來選擇最小的元素。
三、二維條碼
什么是二維條碼?
二維條碼能夠在橫向和縱向兩個方位同時表達信息,因此能在很小的面積內表達大量的信息。
二維條碼可以分為堆疊式二維條碼和矩陣式二維條碼。堆疊式二維條碼形態上是由多行短截的一維條碼堆疊而成;矩陣式二維條碼以矩陣的形式組成,在矩陣相應元素位置上用“點”表示二進制“1”,用“空”表示二進制“0”,由“點”和“空”的排列組成代碼。
堆疊式二維條碼,有代表性的包括PDF417、Code 49、Code 16K等。矩陣式二維條碼有代表性的是Code one、Aztec、Date Matrix、QR碼等。
二維條碼的特點:
1.高密度編碼,信息容量大:可容納多達1850個大寫字母或2710個數字或1108個字節,或500多個漢字,比普通條碼信息容量約高幾十倍。
2.編碼范圍廣:該條碼可以把圖片、聲音、文字、簽字、指紋等可以數字化的信息進行編碼,用條碼表示出來;可以表示多種語言文字;可表示圖像數據。
3.容錯能力強,具有糾錯功能:這使得二維條碼因穿孔、污損等引起局部損壞時,照樣可以正確得到識讀,損毀面積達50%仍可恢復信息。
4.譯碼可靠性高:它比普通條碼譯碼錯誤率百萬分之二要低得多,誤碼率不超過千萬分之一。
5.可引入加密措施:保密性、防偽性好
6.成本低,易制作,持久耐用。
7.條碼符號形狀、尺寸大小比例可變
8.二維條碼可以使用激光或CCD閱讀器識讀。
Android上使用Zxing識別條形碼和二維碼。ZXing是個很經典的條碼/二維碼識別的開源類庫。也可以采用Barcode Scanner。
四、消息推送:
要獲取服務器上不定時更新的信息一般來說有兩種方法,第一種是客戶端使用Pull(拉)的方式,隔一段時間就去服務器上獲取信息,看是否有更新的信息出現。第二種就是服務器使用Push(推送)的方式,當服務器端有新信息了,則把最新的信息Push到客戶端上。
雖然Pull和Push兩種方式都能實現獲取服務器端更新信息的功能,但是明顯來說Push is better than pull。因為Pull方式更費客戶端的網絡流量,更主要的是費電量。
Android Cloud to Device Messaging (C2DM)是一個用來幫助開發者從服務器向Android應用程序發送數據的服務。該服務提供了一個簡單的、輕量級的機制,允許服務器可以通知移動應用程序直接與服務器進行通信,以便于從服務器獲取應用程序更新和用戶數據。C2DM服務負責處理諸如消息排隊等事務并向運行于目標設備上的應用程序分發這些消息。即后來的GCM,在國內難以使用。
在Android下最有的方式應該采取XMPP協議推送Android信息:
首先介紹一下XMPP基于可擴展標記語言(XML)的協議,它用于即時消息(IM)以及在線探測。這個協議可能最終允許因特網用戶向因特網上的其他任何人發送即時消息。
Google官方的C2DM服務器底層也是采用XMPP協議進行的封裝。
androidpn是一個基于XMPP協議的java開源Androidpush notification實現。它包含了完整的客戶端和服務器端。該服務器端基本是在另外一個開源工程openfire基礎上修改實現的。它的實現示意圖如下:
androidpn(韓國開發)客戶端需要用到一個基于java的開源XMPP協議包asmack,這個包同樣也是基于openfire下的另外一個開源項目smack,不過我們不需要自己編譯,可以直接把androidpn客戶端里面的asmack.jar拿來使用。客戶端利用asmack中提供的XMPPConnection類與服務器建立持久連接,并通過該連接進行用戶注冊和登錄認證,同樣也是通過這條連接,接收服務器發送的通知。
androidpn服務器端也是java語言實現的,基于openfire開源工程,不過它的Web部分采用的是spring框架,這一點與 openfire是不同的。Androidpn服務器包含兩個部分,一個是偵聽在5222端口上的XMPP服務,負責與客戶端的 XMPPConnection類進行通信,作用是用戶注冊和身份認證,并發送推送通知消息。另外一部分是Web服務器,采用一個輕量級的HTTP服務器,負責接收用戶的Web請求。服務器架構如下:
最上層包含四個組成部分,分別是SessionManager,Auth Manager,PresenceManager以及Notification Manager。SessionManager負責管理客戶端與服務器之間的會話,Auth Manager負責客戶端用戶認證管理,Presence Manager負責管理客戶端用戶的登錄狀態,NotificationManager負責實現服務器向客戶端推送消息功能。
服務器端界面如下,分別對應了上述的幾個功能模塊:
發送以后,我們可以在手機端看到接收的消息:
這個解決方案的最大優勢就是簡單,我們不需要象C2DM那樣依賴操作系統版本,也不會擔心某一天Google服務器不可用。利用XMPP協議我們還可以進一步的對協議進行擴展,實現更為完善的功能。
采用這個方案,目前只能發送文字消息,不過對于推送來說一般足夠了,因為我們不能指望通過推送得到所有的數據,一般情況下,利用推送只是告訴手機端服務器發生了某些改變,當客戶端收到通知以后,應該主動到服務器獲取最新的數據,這樣才是推送服務的完整實現。
國內的推送服務商:
個推:個推與新浪微博之間實現合作。這大大加強了其知名度。個推通過IP通道實現用戶間免費實時通訊服務,支持文字,圖片,語音,視頻及文件的傳輸。個推注重的是整體策略的布局,對于企業型APP來說較為實用!
極光:極光推送在推送方面表現出的是短平快,極光推送可以發送消息,效果分析圖表等。與此同時,極光推送開通了定制化服務,可以推送時間、用戶群、位置等。極光推送更偏重于個人或小團體的APP,靈活、迅速是其優勢所在。
蝴蝶:蝴蝶云推送將發展的核心定位在了云端系統,制約蝴蝶云推送發展的,一是云端技術的發展能力;二是地面部隊的推廣,蝴蝶云推送能否讓APP開發者所采用,需要蝴蝶推送團隊仔細考量。
智游:針對APP開發,穩定維護長連接是推送平臺的一個基礎,當運營商在2G,2.5G的條件下,出現了網絡超齡超負荷,造成信令風暴,以至于刻意縮短空閑連接的釋放超時,以起到節省信道資源的目的。智游推送團隊為了維護長連接的穩定性,避免在信令風暴出現的時候,保持連接的穩定性,使用了多項核心技術,由于涉及到公司核心業務,需要保密。
個推,1. 第三方客戶端集成個推SDK。
2. 第三方客戶端啟動的時候,調用SDK接口,啟動推送服務,SDK后臺運行并維護和個推服務端的長連接,實現SDK注冊和登錄。
3. 第三方服務端調用個推服務器的接口,將要發送的數據通過個推服務器發送到指定身份的個推SDK當中。
4. 個推SDK解析定制數據,并且把第三方服務器透傳的數據發送給第三方客戶端,第三方客戶端根據服務器的數據做出相應的動作或者展現。
五、google語音識別技術
原理
在Android 4.1中,Google加入了被稱為“神經網絡”的技術,這種技術將語音識別錯誤率降低了25%以上。當你對你的Android手機說出一個要搜索的關鍵字時,你的聲音會轉變成聲譜圖,被分成8段然后傳送到不同的服務器上。Google通過分析以前記錄過的無數聲譜圖,來推測你究竟說了什么。
在這個處理過程中,Google做了兩件事:
1,從聲譜圖中分辨出元音和輔音;
2,從元音和輔音的組合中推測出單詞,然后再做進一步處理。這就和你在看見一張圖片的時候是一樣的:你的大腦總會先尋找這張圖片的邊緣再看內容。
語音識別,借助于云端技術可以識別用戶的語音輸入,包括語音控制等技術,使用前需要安裝語音識別服務。
Android開發實現:
啟動,RecognizerIntent。
設置語言模式
開始語音識別
把語音傳至google服務器,云端搜索
搜索完畢,傳回數據,得到語音字符
六、JNI
JNI是java NativeInterface,java本地接口。與硬件或操作系統進行交互,提高程序性能會使用C/C++編寫的代碼,Java代碼與其他語言編寫的代碼進行交互,于是產生了JNI。
書寫步驟:
(1)編寫帶有native聲明的方法的類。
(2)javac編譯該java類,javah+java類名生成擴展名為h的頭文件。
(3)C/C++實現本地方法。(native聲明的方法)
(4)將C/C++編寫的文件生成動態鏈接庫。
編寫java程序:
編譯:Javac HelloWorld.java
生成頭文件:Javah HelloWorld
編寫本地方法:本地方法名和頭文件本地方法名相同。
linux下何謂.so文件:1. 用過windows的同學應該都知道 .dll文件吧, 這二者有什么共通之處呢,其實 .so文件就跟.dll文件差不多.
2.一般來說.so文件就是常說的動態鏈接庫,都是C或C++編譯出來的。與Java比較就是:它通常是用的Class文件(字節碼).
3.Linux下的.so文件時不能直接運行的,一般來講,.so文件稱為共享庫.
4.dll也是由C/C++編寫,由VC工具編譯。
GDB是GNU開源組織發布的一個強大的UNIX下的程序調試工具。
NDK全稱:NativeDevelopment Kit。
1、NDK是一系列工具的集合。
NDK提供了一系列的工具,幫助開發者快速開發C(或C++)的動態庫,并能自動將so和java應用一起打包成apk。這些工具對開發者的幫助是巨大的。[1]
NDK集成了交叉編譯器,并提供了相應的mk文件隔離平臺、CPU、API等差異,開發人員只需要簡單修改mk文件(指出“哪些文件需要編譯”、“編譯特性要求”等),就可以創建出so。
NDK可以自動地將so和Java應用一起打包,極大地減輕了開發人員的打包工作。
2、NDK提供了一份穩定、功能有限的API頭文件聲明。
NDK產生so動態鏈接庫供JNI調用。
顯示大量圖片時,如何管理內存?
盡量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource來設置 一張大圖,因為這些函數在完成decode后,最終都是通過java層的createBitmap來完成的,需要消耗更多內存。
因此,改用先通過BitmapFactory.decodeStream方法,創建出一個bitmap,再將其設為ImageView的 source,decodeStream最大的秘密在于其直接調用JNI>>nativeDecodeAsset()來完成decode,無需再使用java層的createBitmap,從而節省了java層的空間。
如果在讀取時加上圖片的Config參數,可以跟有效減少加載的內存,從而跟有效阻止拋out of Memory異常
內存溢出解決辦法:
(1) 壓縮圖片
(2) 優化Dalvik虛擬機的堆內存分配,在oncreate方法里面調用下列方法;VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION);
(3)及時回收Bitmap對象
(4)HandlerThread(異步加載)+LruCache(內存緩存)+DiskLruCache(硬盤緩存).
來自:http://blog.csdn.net/u010152805/article/details/12852191