Android環(huán)境下主UI線程與子線程通信機(jī)制研究論文

    時(shí)間:2024-08-01 09:18:43 通信工程畢業(yè)論文 我要投稿
    • 相關(guān)推薦

    Android環(huán)境下主UI線程與子線程通信機(jī)制研究論文

      1問(wèn)題的引出

    Android環(huán)境下主UI線程與子線程通信機(jī)制研究論文

      如果需要用手機(jī)從網(wǎng)絡(luò)上下載一個(gè)圖片到自己的手機(jī)上,在onCreate方法中可以如下圖1所示的代碼。通過(guò)代碼會(huì)獲取并顯示所需要的位圖。但其中隱藏著一個(gè)非常危險(xiǎn)的問(wèn)題——代碼本身就是運(yùn)行在主線程上。Android系統(tǒng)只能運(yùn)行一個(gè)主線程,而且只有主線程能夠與屏幕之間進(jìn)行任意權(quán)限級(jí)別的交互。這意味著,當(dāng)代碼等待網(wǎng)絡(luò)回傳圖片數(shù)據(jù)的時(shí)候,任何內(nèi)容都無(wú)法顯示到屏幕上。這段獲取圖片的代碼會(huì)限制在手機(jī)上任意地方執(zhí)行任意操作。所以如果主線程被綁架,那么它在被釋放之前,系統(tǒng)就不會(huì)響應(yīng)按單擊事件,不能接電話,屏幕上不能顯示任何內(nèi)容。這對(duì)于手機(jī)用戶來(lái)說(shuō)是災(zāi)難性的。

      2什么是子線程

      為了有效解決手機(jī)被綁架的問(wèn)題,提高用戶體驗(yàn),提出了子線程。在Android的布局界面中,可以實(shí)現(xiàn)按鈕的單擊、TextView內(nèi)容的修改,所有這些與界面控件相關(guān)的操作,實(shí)際上都是由主UI線程在負(fù)責(zé)運(yùn)行。但有時(shí)候,程序會(huì)執(zhí)行一些耗時(shí)的操作,比如復(fù)雜的計(jì)算、訪問(wèn)網(wǎng)絡(luò),下載數(shù)據(jù),查詢數(shù)據(jù)庫(kù)、甚至包括讓線程休眠等,這些操作如果放到主UI線程中執(zhí)行,會(huì)造成主UI線程無(wú)法及時(shí)響應(yīng)用戶在界面上的操作,造成界面假死的狀態(tài)。一般的解決方案是將耗時(shí)的操作交給另外一個(gè)子線程來(lái)執(zhí)行,從而保證主UI線程的暢通。有時(shí)候子線程在完成了一部分的耗時(shí)操作以后,希望能夠在主界面上有所體現(xiàn),此時(shí)子線程是不能夠直接操作界面控件的,它必須通過(guò)消息的方式告知主UI線程進(jìn)行控件更新。

      3子線程與主UI線程的通信原理

      Android應(yīng)用程序運(yùn)行時(shí),一個(gè)主線程被創(chuàng)建(也稱(chēng)作UI線程),此線程主要負(fù)責(zé)處理UI相關(guān)的事件,由于Android采用UI單線程模型,所以只能在主線程中對(duì)UI元素進(jìn)行操作,如果在非UI線程直接對(duì)UI進(jìn)行了操作,則會(huì)報(bào)錯(cuò),另外,對(duì)于運(yùn)算量較大的操作和IO操作,我們需要新開(kāi)線程來(lái)處理這些工作,以免阻塞UI線程,子線程與主線程之間通信原理如下圖2所示。

      從上圖2可以看出,要完成子線程與主UI線程之間的通信,需要配合多個(gè)類(lèi)來(lái)完成。其中Thread類(lèi)負(fù)責(zé)線程工作,要?jiǎng)?chuàng)建該類(lèi)需要實(shí)現(xiàn)Runnable接口的run()方法,run()方法中一般是耗時(shí)操作的代碼。第二個(gè)類(lèi)是Message類(lèi),用來(lái)描述消息,在Message對(duì)象中可以存儲(chǔ)一些信息。第三個(gè)類(lèi)是Handler類(lèi),用來(lái)發(fā)送和接受消息,要?jiǎng)?chuàng)建該類(lèi)需要實(shí)現(xiàn)handleMessage(Messagemsg)方法,該方法會(huì)在Handler對(duì)象接收到消息時(shí)被調(diào)用。那么這三個(gè)類(lèi)之間協(xié)同合作,才能有序地完成子線程與主UI線程之間的通信。

      3.1Thread類(lèi)

      要?jiǎng)?chuàng)建子線程對(duì)象,就需要使用Thread類(lèi)。要?jiǎng)?chuàng)建該類(lèi)需要實(shí)現(xiàn)Runnable接口的抽象方法run(),在run()方法中需要添加子線程所要運(yùn)行任務(wù)的代碼。其次,Sleep(longtime)方法是讓線程休眠,其中time為休眠的時(shí)間,單位時(shí)毫秒。最后一定要用start()方法運(yùn)行線程。之后該子線程就可以開(kāi)始工作了。

      子線程在特定情況下需要通過(guò)Handler發(fā)送Message給主UI線程,委托主UI線程進(jìn)行一些與界面相關(guān)的處理,所以,發(fā)送消息的Handler類(lèi)也是其中的一個(gè)很重要的類(lèi)。

      3.2Message類(lèi)

      Message類(lèi)型的消息中包含了一個(gè)int類(lèi)型的成員對(duì)象what,利用what可以區(qū)分不同的消息類(lèi)型。返回值有兩種情況,如果消息成功放置到消息隊(duì)列則返回true,否則返回false。

      3.3Handler類(lèi)

      發(fā)送消息:所使用的類(lèi)為Handler類(lèi),方法為publicbooleansendMessage(Messagemsg),其中,msg是消息對(duì)象。Message類(lèi)型的消息中包含了一個(gè)int類(lèi)型的成員對(duì)象what,利用what可以區(qū)分不同的消息類(lèi)型。子線程將消息發(fā)送給主線程,主線程收到消息之后,會(huì)根據(jù)傳過(guò)來(lái)的消息信號(hào)的不同做不同的動(dòng)作。如果消息號(hào)為STOP,則子線程結(jié)束消息的傳送,如果消息號(hào)為CONTINUE,則繼續(xù)傳送消息。當(dāng)子線程的狀態(tài)發(fā)生變化,則在子線程中發(fā)出Message,通知更新UI。

      接收處理消息:使用的是Handler類(lèi),方法為publicvoidhan

      dleMessage(Messagemsg),通過(guò)判斷msg.what可以區(qū)分不同的消息類(lèi)型。根據(jù)不同的消息類(lèi)型,主UI線程會(huì)產(chǎn)生不同的動(dòng)作來(lái)響應(yīng)子線程。

      4子線程與主線程之間通信的實(shí)例

      該程序的界面如圖3所示,界面中存在一個(gè)水平進(jìn)度條和一個(gè)大環(huán)形進(jìn)度條,以及一個(gè)TextView來(lái)顯示“界面加載中。。。”。運(yùn)行中:水平滾動(dòng)條每1秒前進(jìn)一格,當(dāng)進(jìn)度條的進(jìn)度達(dá)到100%時(shí),TextView顯示“頁(yè)面加載完畢”。

      分析:要完成這樣的任務(wù),需要讓程序循環(huán)性地休眠1s后,更新水平進(jìn)度條。但是如果讓主程序休眠,會(huì)導(dǎo)致界面假死狀態(tài),造成用戶使用感受的下降,如何解決?就用到了上面所提到的線程。實(shí)現(xiàn)過(guò)程代碼如下圖4所示。

      5需要改善的幾個(gè)問(wèn)題

      (1)設(shè)置線程的中斷標(biāo)記,有效地控制線程的進(jìn)度。在Eclipse中創(chuàng)建Android項(xiàng)目,通過(guò)實(shí)現(xiàn)Runnable接口來(lái)創(chuàng)建線程、開(kāi)啟線程、讓線程休眠指定的時(shí)間,除此之外,還可以中斷線程。當(dāng)需要中斷指定線程時(shí),可以使用Thread類(lèi)提供的interrupt()方法來(lái)實(shí)現(xiàn)。使用interrupt()方法可以向指定的線程發(fā)送一個(gè)中斷請(qǐng)求,此時(shí)可以使用一個(gè)boolean型的標(biāo)記變量來(lái)記錄該線程的中斷狀態(tài),并通過(guò)該標(biāo)記變量來(lái)控制循環(huán)的執(zhí)行與停止。

      (2)子線程開(kāi)啟消息循環(huán)。在Andorid中一個(gè)線程對(duì)應(yīng)一個(gè)Looper對(duì)象,而一個(gè)Looper對(duì)象對(duì)應(yīng)一個(gè)MessageQueue消息隊(duì)列,消息隊(duì)列里面用于存放消息。Looper對(duì)象用來(lái)為一個(gè)線程開(kāi)啟一個(gè)消息循環(huán),用來(lái)操作消息隊(duì)列。默認(rèn)情況下,系統(tǒng)自動(dòng)為主線程開(kāi)啟消息循環(huán),新建子線程中則需要手動(dòng)開(kāi)啟,否則會(huì)拋出異常。

      6結(jié)語(yǔ)

      Android的應(yīng)用程序的多線程編程為我們充分利用系統(tǒng)資源提供了便利,同時(shí)也為設(shè)計(jì)復(fù)雜UI和耗時(shí)操作提供了途徑,提升了手機(jī)用戶的使用體驗(yàn)。在子線程與UI主線程通信過(guò)程中,用到了try{}catch{Exceptione}{}語(yǔ)句,這個(gè)語(yǔ)法是代碼異常處理的,如果沒(méi)有try的話,出現(xiàn)異常會(huì)導(dǎo)致程序崩潰。而try則可以保證程序的正常運(yùn)行下去,并且輸出為什么出錯(cuò),對(duì)程序的維護(hù)有很大的幫助。

      另外在主線程上應(yīng)該避免下列操作:與網(wǎng)絡(luò)相關(guān)的操作;需要對(duì)文件系統(tǒng)進(jìn)行讀寫(xiě)操作的任務(wù);任何種類(lèi)的繁重事務(wù)處理(如圖片或視頻修改);在等待某個(gè)事務(wù)完成時(shí)會(huì)阻礙線程執(zhí)行的任務(wù)等等。因此,作為一般規(guī)律,如果不涉及對(duì)用戶界面的設(shè)置或修改,就不要放在主線程上。

      參考文獻(xiàn)

      [1]余永佳,趙佩華,等.Android應(yīng)用開(kāi)發(fā)基礎(chǔ)[M].北京:機(jī)械工業(yè)出版社,2014.

      [2]蓋索林.Android開(kāi)發(fā)入門(mén)指南(第二版)[M].北京:人民郵電出版社,2013.

    【Android環(huán)境下主UI線程與子線程通信機(jī)制研究論文】相關(guān)文章:

    論文:Linux進(jìn)程和線程的基礎(chǔ)與管理08-18

    在Windows2000下用多線程實(shí)現(xiàn)1394串行總線通信10-02

    單片機(jī)系統(tǒng)中的多任務(wù)多線程機(jī)制的實(shí)現(xiàn)09-18

    多線程技術(shù)在邊緣檢測(cè)方面的應(yīng)用10-06

    PPLive通信機(jī)制與流量識(shí)別研究08-20

    船舶物聯(lián)網(wǎng)遠(yuǎn)程數(shù)據(jù)通信機(jī)制研究論文07-16

    全媒體環(huán)境下新聞?wù)Z言研究論文07-01

    基于AMF的Android數(shù)據(jù)通信論文10-29

    通信IPRAN通信技術(shù)傳輸研究論文08-31

    能電網(wǎng)環(huán)境下的電力通信技術(shù)探析論文09-16

    91久久大香伊蕉在人线_国产综合色产在线观看_欧美亚洲人成网站在线观看_亚洲第一无码精品立川理惠

      亚洲国产日韩欧美性 | 中文字幕在线一级 | 伊伊人成亚洲综合人网 | 亚洲日韩乱码中文字幕 | 中文字幕亚洲日韩欧美一区 | 亚洲一区在线曰日韩在线 |