三個(gè)手指向屏幕傳遞的東西可以被抽象為一個(gè)個(gè)的觸摸點(diǎn)(Pointer)。
站在用戶的角度思考問(wèn)題,與客戶深入溝通,找到東寧網(wǎng)站設(shè)計(jì)與東寧網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、申請(qǐng)域名、網(wǎng)絡(luò)空間、企業(yè)郵箱。業(yè)務(wù)覆蓋東寧地區(qū)。
按照觸碰到屏幕的順序來(lái)分,每個(gè)Pointer都有一個(gè)index,這個(gè)算法有點(diǎn)特別?,F(xiàn)在舉例來(lái)幫助你理解。
看到Index,你是否想起了數(shù)組下標(biāo)?沒(méi)錯(cuò)你可以認(rèn)為這三個(gè)Pointer被安置在了一個(gè)數(shù)組里,數(shù)組大小為Pointer的個(gè)數(shù)。
有一天,我拿右手的三根手指(食指A,中指B,無(wú)名指C)在屏幕上做滑動(dòng)手勢(shì),我是 先用食指A 接觸屏幕, 再拿中指B 接觸到, 最后拿無(wú)名指C 接觸到屏幕,這三根手指的起始位置都貼著屏幕的 最左邊 也就是 X軸接近于0 的地方。這時(shí)候 以觸碰到屏幕的次序?yàn)橐罁?jù) ,這三根手指分別被賦予了各自的index,其中 食指A最先 接觸,index為 0 ; 中指B第二個(gè) 接觸,index為 1 ; 無(wú)名指C第三個(gè) 接觸,index為 2 ;
無(wú)聊透頂?shù)奈以谕一瑒?dòng)的過(guò)程中,把 中指B松開(kāi) 了,這下 index為1的中指B 從數(shù)列中被移除了,安卓說(shuō):哦, index為1 的這個(gè)地方被移除過(guò)Pointer,并且這個(gè)index為1的位置還是 第一個(gè)被移除 的,我記錄下來(lái)了。
移除完后呢,總不能空著吧,現(xiàn)在就 兩個(gè) Pointer在屏幕上,我總不能按三個(gè)來(lái)算吧。我是把目前 index為0 的 Pointer(食指A) 轉(zhuǎn)移到index為1的位置上,還是把目前 index為2 的 Pointer( 無(wú)名指C ) 轉(zhuǎn)移到index為1的位置上呢?
是的,谷歌和你一樣都很機(jī)智,他們把 index為2的向前移 了,這樣數(shù)組尺寸就變小了。
既然之前說(shuō)了我無(wú)聊透頂,目前我好像還不夠無(wú)聊,為了貫徹這個(gè)詞語(yǔ),我在快要滑到 屏幕右側(cè) 的時(shí)候,我 又加了 一根手指進(jìn)來(lái),這次加的還不是原來(lái)那根 黃金中指B ,而是我的 小拇指D !而且非常風(fēng)騷地伸到了屏幕的 左側(cè) 去了,這意味著我這個(gè) Pointer小拇指D的X值是很小 的,正當(dāng)我盯著 index為2的位置 觀看我風(fēng)騷小拇指創(chuàng)造的位置數(shù)據(jù)時(shí),驚奇地發(fā)現(xiàn)我的小拇指被賦予的 index竟然為1?。?! 在后來(lái)的實(shí)驗(yàn)中, 不管我放的 是原來(lái)率先釋放的中指B還是什么一陽(yáng)指,衛(wèi)生指。他們被賦予的 index都是1?。?!
比如index分別為0,1,2,3的四個(gè)Pointer,其中 index為2的Pointer率先 中途移除,然后 index為3的Pointer接著被移除 ,系統(tǒng)將 記錄 哪個(gè)index是 最先出現(xiàn)空缺 的,哪個(gè)index是 第二個(gè)出現(xiàn)空缺 的,然后接下來(lái)新產(chǎn)生的Pointer將按 產(chǎn)生的順序 ,先來(lái)的放到最先出現(xiàn)空缺的index上,在這里,最新來(lái)的Pointer將被放置在 最先出現(xiàn)空缺的 index為 2 的位置上。 下一個(gè)來(lái)的 Pointer將被放置在 index為3 的位置上.
快速排序(Quick Sort)的基本思想:通過(guò)一趟排序?qū)⒋庞涗浄指舫瑟?dú)立的兩部分,其中一部分記錄的關(guān)鍵字均比另一部分的關(guān)鍵字小,則可分別對(duì)這兩部分記錄繼續(xù)進(jìn)行排序,以達(dá)到整個(gè)序列有序。
快速排序使用分治法來(lái)把一個(gè)串(list)分為兩個(gè)子串(sub-lists)。具體算法描述如下:
Android中對(duì)于圖形界面以及多媒體的相關(guān)操作比較容易實(shí)現(xiàn)。而且對(duì)于大多數(shù)
手機(jī)
用戶來(lái)說(shuō),他們主要也就是根據(jù)這些方面的功能來(lái)對(duì)系統(tǒng)那個(gè)進(jìn)行修改。我們可以通過(guò)本文介紹的Android多媒體框架的源碼解讀,來(lái)具體分析一下這方面的基本知識(shí)。
Android多媒體框架的代碼在以下目錄中:external/opencore/。這個(gè)目錄是Android多媒體框架的根目錄,其中包含的子目錄如下所示:
* android:這里面是一個(gè)上層的庫(kù),它基于PVPlayer和PVAuthor的SDK實(shí)現(xiàn)了一個(gè)為Android使用的Player和Author。
* baselibs:包含數(shù)據(jù)結(jié)構(gòu)和線程安全等內(nèi)容的底層庫(kù)
* codecs_v2:這是一個(gè)內(nèi)容較多的庫(kù),主要包含編解碼的實(shí)現(xiàn),以及一個(gè)OpenMAX的實(shí)現(xiàn)
* engines:包含PVPlayer和PVAuthor引擎的實(shí)現(xiàn)
* extern_libs_v2:包含了khronos的OpenMAX的頭文件
* fileformats:文件格式的據(jù)具體解析(parser)類
* nodes:編解碼和文件解析的各個(gè)node類。
* oscl:操作系統(tǒng)兼容庫(kù)
* pvmi: 輸入輸出控制的抽象接口
* protocols:主要是與網(wǎng)絡(luò)相關(guān)的RTSP、RTP、HTTP等協(xié)議的相關(guān)內(nèi)容
* pvcommon:pvcommon庫(kù)文件的Android.mk文件,沒(méi)有源文件。
* pvplayer:pvplayer庫(kù)文件的Android.mk文件,沒(méi)有源文件。
* pvauthor:pvauthor庫(kù)文件的Android.mk文件,沒(méi)有源文件。
* tools_v2:編譯工具以及一些可注冊(cè)的模塊。
Splitter的定義與初始化
以wav的splitter為例,在fileformats目錄下有解析wav文件格式的pvwavfileparser.cpp文件,在nodes目錄下有pvmf_wavffparser_factory.cpp,pvmf_wavffparser_node.h, pvmf_wavffparser_port.h等文件。
我們由底往上看,vwavfileparser.cpp中的PV_Wav_Parser類有InitWavParser(),GetPCMData(),RetrieveFileInfo()等解析wav格式的成員函數(shù),此類應(yīng)該就是最終的解析類。我們搜索PV_Wav_Parser類被用到的地方可知,在PVMFWAVFFParserNode類中有PV_Wav_Parser的一個(gè)指針成員變量。
再搜索可知,PVMFWAVFFParserNode類是通過(guò)PVMFWAVFFParserNodeFactory的CreatePVMFWAVFFParserNode()成員函數(shù)生成的。而CreatePVMFWAVFFParserNode()函數(shù)是在PVPlayerNodeRegistry::PVPlayerNodeRegistry()類構(gòu)造函數(shù)中通過(guò)PVPlayerNodeInfo類被注冊(cè)到Oscl_VectorPVPlayerNodeInfo, OsclMemAllocator 的vector中,在這個(gè)構(gòu)造函數(shù)中,AMR,mp3等node也是同樣被注冊(cè)的。
由上可知,Android多媒體框架中對(duì)splitter的管理也是與ffmpeg等類似,都是在框架的初始化時(shí)注冊(cè)的,只不過(guò)Opencore注冊(cè)的是每個(gè)splitter的factory函數(shù)。
綜述一下splitter的定義與初始化過(guò)程:
每個(gè)splitter都在fileformats目錄下有個(gè)對(duì)應(yīng)的子目錄,其下有各自的解析類。
每個(gè)splitter都在nodes目錄下有關(guān)對(duì)應(yīng)的子目錄,其下有各自的統(tǒng)一接口的node類和node factory類。
播放引擎PVPlayerEngine類中有PVPlayerNodeRegistry iPlayerNodeRegistry成員變量。
在PVPlayerNodeRegistry的構(gòu)造函數(shù)中,將 AMR, AAC, MP3等splitter的輸入與輸出類型標(biāo)示和node factory類中的create node與release delete接口通過(guò)PVPlayerNodeInfo類push到Oscl_VectorPVPlayerNodeInfo, OsclMemAllocator iType成員變量中。
當(dāng)前Splitter的匹配過(guò)程
PVMFStatus PVPlayerNodeRegistry::QueryRegistry(PVMFFormatType aInputType, PVMFFormatType aOutputType, Oscl_VectorPVUuid, OsclMemAllocator aUuids)函數(shù)的功能是根據(jù)輸入類型和輸出類型,在已注冊(cè)的node vector中尋找是否有匹配的node,有的話傳回其唯一識(shí)別標(biāo)識(shí)PVUuid。
從QueryRegistry這個(gè)函數(shù)至底向上搜索可得到,在android中splitter的匹配過(guò)程如下:
android_media_MediaPlayer.cpp之中定義了一個(gè)JNINativeMethod(JAVA本地調(diào)用方法)類型的數(shù)組gMethods,供java代碼中調(diào)用MultiPlayer類的setDataSource成員函數(shù)時(shí)找到對(duì)應(yīng)的c++函數(shù)
1.{"setDataSource", "(Ljava/lang/String;)V", (void *)
android_media_MediaPlayer_setDataSource},
2.static void android_media_MediaPlayer_setDataSource
(JNIEnv *env, jobject thiz, jstring path)
此函數(shù)中先得到當(dāng)前的MediaPlayer實(shí)例,然后調(diào)用其setDataSource函數(shù),傳入路徑
3.status_t MediaPlayer::setDataSource(const char *url)
此函數(shù)通過(guò)調(diào)getMediaPlayerService()先得到當(dāng)前的MediaPlayerService, const spIMediaPlayerService service(getMediaPlayerService());
然后新建一個(gè)IMediaPlayer變量, spIMediaPlayer player(service-create(getpid(), this, fd, offset, length));
在spIMediaPlayer MediaPlayerService::create(pid_t pid, const spIMediaPlayerClient client, const char* url)中
調(diào)status_t MediaPlayerService::Client::setDataSource(const char *url)函數(shù),Client是MediaPlayerService的一個(gè)內(nèi)部類。
在MediaPlayerService::Client::setDataSource中,調(diào)spMediaPlayerBase MediaPlayerService::Client::createPlayer(player_type playerType)
生成一個(gè)繼承自MediaPlayerBase的PVPlayer實(shí)例。
1.概念:
Base64是一種用64個(gè)字符(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/)來(lái)表示二進(jìn)制數(shù)據(jù)的方法,只是一種編碼方式,所以不建議使用Base64來(lái)進(jìn)行加密數(shù)據(jù)。
2.由來(lái):
為什么會(huì)有Base64編碼呢?因?yàn)橛?jì)算機(jī)中數(shù)據(jù)是按ascii碼存儲(chǔ)的,而ascii碼的128~255之間的值是不可見(jiàn)字符。在網(wǎng)絡(luò)上交換數(shù)據(jù)時(shí),比如圖片二進(jìn)制流的每個(gè)字節(jié)不可能全部都是可見(jiàn)字符,所以就傳送不了。最好的方法就是在不改變傳統(tǒng)協(xié)議的情況下,做一種擴(kuò)展方案來(lái)支持二進(jìn)制文件的傳送,把不可打印的字符也能用可打印字符來(lái)表示,所以就先把數(shù)據(jù)先做一個(gè)Base64編碼,統(tǒng)統(tǒng)變成可見(jiàn)字符,降低錯(cuò)誤率。
3.示例:
加密和解密用到的密鑰是相同的,這種加密方式加密速度非??欤m合經(jīng)常發(fā)送數(shù)據(jù)的場(chǎng)合。缺點(diǎn)是密鑰的傳輸比較麻煩。
1.DES
DES全稱為Data Encryption Standard,即數(shù)據(jù)加密標(biāo)準(zhǔn),是一種使用 密鑰加密 的塊算法。
DES算法把64位的明文輸入塊變?yōu)?4位的密文輸出塊,它所使用的密鑰也是64位,密鑰事實(shí)上是56位參與DES運(yùn)算(第8、16、24、32、40、48、56、64位是校驗(yàn)位,使得每個(gè)密鑰都有奇數(shù)個(gè)1)分組后的明文組和56位的密鑰按位替代或交換的方法形成密文組的加密方法。
2.3DES
3DES(或稱為Triple DES)是三重 數(shù)據(jù)加密算法 (TDEA,Triple Data Encryption Algorithm)塊密碼的通稱。是DES向AES過(guò)渡的加密算法,它使用3條56位的密鑰對(duì)數(shù)據(jù)進(jìn)行三次加密。是DES的一個(gè)更安全的變形。它以DES為基本模塊,通過(guò)組合分組方法設(shè)計(jì)出分組加密算法。比起最初的DES,3DES更為安全。
3.AES
AES全稱Advanced Encryption Standard,即高級(jí)加密標(biāo)準(zhǔn),當(dāng)今最流行的對(duì)稱加密算法之一,是DES的替代者。支持三種長(zhǎng)度的密鑰:128位,192位,256位。
AES算法是把明文拆分成一個(gè)個(gè)獨(dú)立的明文塊,每一個(gè)明文塊長(zhǎng)128bit。這些明文塊經(jīng)過(guò)AES加密器的復(fù)雜處理,生成一個(gè)個(gè)獨(dú)立的密文塊,這些密文塊拼接在一起,就是最終的AES加密結(jié)果。
但是這里涉及到一個(gè)問(wèn)題:假如一段明文長(zhǎng)度是192bit,如果按每128bit一個(gè)明文塊來(lái)拆分的話,第二個(gè)明文塊只有64bit,不足128bit。這時(shí)候怎么辦呢?就需要對(duì)明文塊進(jìn)行填充(Padding):
AES的工作模式,體現(xiàn)在把明文塊加密成密文塊的處理過(guò)程中。
加密和解密用的密鑰是不同的,這種加密方式是用數(shù)學(xué)上的難解問(wèn)題構(gòu)造的,通常加密解密的速度比較慢,適合偶爾發(fā)送數(shù)據(jù)的場(chǎng)合。優(yōu)點(diǎn)是密鑰傳輸方便。
1.SHA
安全散列算法(英語(yǔ):Secure Hash Algorithm,縮寫(xiě)為SHA)是一個(gè)密碼散列函數(shù)家族,是FIPS所認(rèn)證的安全散列算法。能計(jì)算出一個(gè)數(shù)字消息所對(duì)應(yīng)到的,長(zhǎng)度固定的字符串(又稱消息摘要)的算法,且若輸入的消息不同,它們對(duì)應(yīng)到不同字符串的機(jī)率很高。
SHA分為SHA-1、SHA-224、SHA-256、SHA-384,和SHA-512五種算法,后四者有時(shí)并稱為SHA-2。SHA-1在許多安全協(xié)定中廣為使用,包括TLS和SSL、PGP、SSH、S/MIME和IPsec,曾被視為是MD5(更早之前被廣為使用的雜湊函數(shù))的后繼者。但SHA-1的安全性如今被密碼學(xué)家嚴(yán)重質(zhì)疑;雖然至今尚未出現(xiàn)對(duì)SHA-2有效的攻擊,它的算法跟SHA-1基本上仍然相似;因此有些人開(kāi)始發(fā)展其他替代的雜湊算法。
2.RSA
RSA算法1978年出現(xiàn),是第一個(gè)既能用于數(shù)據(jù)加密也能用于數(shù)字簽名的算法,易于理解和操作。
RSA基于一個(gè)數(shù)論事實(shí):將兩個(gè)大素?cái)?shù)相乘十分容易,但想要對(duì)其乘積進(jìn)行因式分解卻極其困難,因此可以將乘積公開(kāi)作為加密密鑰,即公鑰,而兩個(gè)大素?cái)?shù)組合成私鑰。公鑰是可提供給任何人使用,私鑰則為自己所有,供解密之用。
3.MD5
MD5信息摘要算法 (英語(yǔ):MD5 Message-Digest Algorithm),一種被廣泛使用的密碼散列函數(shù),可以產(chǎn)生出一個(gè)128位(16字節(jié))的散列值,用于確保信息傳輸完整一致。具有如下優(yōu)點(diǎn):
XOR:異或加密,既將某個(gè)字符或者數(shù)值 x 與一個(gè)數(shù)值 m 進(jìn)行異或運(yùn)算得到 y ,則再用 y 與 m 進(jìn)行異或運(yùn)算就可還原為 x。
使用場(chǎng)景:
(1)兩個(gè)變量的互換(不借助第三個(gè)變量);
(2)數(shù)據(jù)的簡(jiǎn)單加密解密。