版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
武漢交通職業(yè)學(xué)院2012-2013學(xué)年第一學(xué)期《Android應(yīng)用程序開發(fā)》期末課程報(bào)告2012年11月項(xiàng)目背景現(xiàn)有的3G技術(shù)和移動(dòng)互聯(lián)網(wǎng)技術(shù)的快速發(fā)展,智能手機(jī)功能的不斷增強(qiáng),讓基于Android平臺(tái)的查詢需求越來越多。本軟件就是利用現(xiàn)有的網(wǎng)絡(luò)快速獲取網(wǎng)絡(luò)上的天氣信息并顯示到手機(jī)終端上,為用戶提供實(shí)時(shí)的天氣查詢和近期天氣查詢服務(wù),為工作、出行等帶來便利。通過WebService等技術(shù)讓用戶體驗(yàn)到前所未有的移動(dòng)計(jì)算。需求分析功能需求在這個(gè)綜合示例中,有一個(gè)顯示天氣情況的用戶界面,可以通過圖片和文字顯示當(dāng)前和未來幾天的天氣狀況,包括溫度、濕度、風(fēng)向和雨雪情況等。這些天氣數(shù)據(jù)是通過后臺(tái)服務(wù)獲取的,這個(gè)后臺(tái)服務(wù)按照一定時(shí)間間隔,從Google上獲取天氣預(yù)報(bào)信息,并將天氣信息保存在后臺(tái)服務(wù)中。示例還需要提供基于SMS短信的天氣數(shù)據(jù)服務(wù),其他手機(jī)用戶可以向本示例所在的手機(jī)上發(fā)送SMS短信,在短信中包含特定的關(guān)鍵字,則可以將已有的天氣情況通過SMS短信回復(fù)給用戶。最后,每個(gè)被發(fā)送的SMS短信都會(huì)被記錄下來,用戶可以瀏覽或刪除這些記錄信息。界面需求從上面的描述中可以基本了解軟件的功能需求,但為了將需求分析過程變得簡(jiǎn)單明了,首先找出用戶界面上需要顯示的內(nèi)容。功能描述中有“顯示天氣情況的用戶界面”和“用戶可以瀏覽或刪除這些記錄信息”,除此以外,一般應(yīng)用軟件還應(yīng)有顯示配置信息的界面。因此,本示例應(yīng)該包含三個(gè)用戶界面:顯示天氣預(yù)報(bào)的用戶界面顯示已發(fā)送SMS短信的用戶界面瀏覽和設(shè)置配置信息的用戶界面內(nèi)部功能從用戶界面出發(fā),分析隱藏在界面后面的內(nèi)部功能,這些功能則是程序正常運(yùn)行的基礎(chǔ)(1)顯示天氣預(yù)報(bào)的用戶界面;①獲取Google的天氣數(shù)據(jù)②保存天氣數(shù)據(jù)信息(2)顯示SMS短信的用戶界面①根據(jù)關(guān)鍵字監(jiān)視SMS短信②發(fā)送包含天氣信息的SMS短信③將發(fā)送SMS短信的相關(guān)信息寫入數(shù)據(jù)庫(kù)(3)瀏覽和設(shè)置配置信息的用戶界面①將用戶設(shè)置的配置信息保存到數(shù)據(jù)庫(kù)②啟動(dòng)時(shí)讀取數(shù)據(jù)庫(kù)中的配置信息③支持恢復(fù)缺省設(shè)置程序設(shè)計(jì)用戶界面設(shè)計(jì)根據(jù)需求中的用戶界面分析,應(yīng)用程序應(yīng)包含三個(gè)主要的用戶界面,每個(gè)用戶界面的顯示內(nèi)容在“顯示天氣預(yù)報(bào)的用戶界面”中,顯示目標(biāo)城市的當(dāng)前的天氣狀況,包括城市名稱、溫度、濕度、風(fēng)向、雨雪情況和獲取數(shù)據(jù)時(shí)間等信息。在界面的下方顯示未來四天的天氣狀況,但僅包括溫度和雨雪情況在“顯示已發(fā)送SMS短信的用戶界面”中,顯示每個(gè)回復(fù)短信的時(shí)間、目標(biāo)手機(jī)號(hào)碼、城市名稱、當(dāng)天的天氣狀況和未來一天的天氣狀況在“瀏覽和設(shè)置配置信息的用戶界面”中,顯示希望獲取天氣預(yù)報(bào)的城市名稱、獲取數(shù)據(jù)的頻率和短信監(jiān)視的關(guān)鍵字,并允許用戶設(shè)置是否提供短信服務(wù),以及是否記錄回復(fù)短信信息用戶界面草圖:數(shù)據(jù)庫(kù)設(shè)計(jì)本示例主要有兩種數(shù)據(jù)需要存儲(chǔ)配置信息:因?yàn)榕渲眯畔⒌臄?shù)據(jù)量很小,從Android支持的存儲(chǔ)方式上分析,可以保存在SharedPreference、文件或SQLite數(shù)據(jù)庫(kù)中SMS短信服務(wù)信息:SMS短信服務(wù)信息是一個(gè)隨著時(shí)間推移而不斷增加的數(shù)據(jù),屬于文本信息,而且有固定的格式,因此適合使用SQLite數(shù)據(jù)庫(kù)進(jìn)行存儲(chǔ)綜合分析這兩個(gè)需要存儲(chǔ)的數(shù)據(jù),選擇SQLite數(shù)據(jù)庫(kù)作為存儲(chǔ)數(shù)據(jù)的方法(1)配置信息:配置信息中主要保存目標(biāo)城市的名稱,訪問Google更新天氣信息的頻率,請(qǐng)求天氣信息服務(wù)短信的關(guān)鍵字,以及是否提供短信服務(wù)和是否記錄短信服務(wù)內(nèi)容配置信息的數(shù)據(jù)庫(kù)表結(jié)構(gòu)(2)SMS短信服務(wù)信息:SMS短信服務(wù)信息主要保存請(qǐng)求天氣服務(wù)短信的發(fā)送者、短信內(nèi)容、接收時(shí)間和回復(fù)信息的內(nèi)容SMS短信服務(wù)信息的數(shù)據(jù)庫(kù)表結(jié)構(gòu)程序設(shè)計(jì)程序模塊設(shè)計(jì):從功能需求上分析,可以將整個(gè)應(yīng)用程序劃分為4個(gè)模塊,分別是用戶界面、后臺(tái)服務(wù)、數(shù)據(jù)庫(kù)適配器和短信監(jiān)聽器。下圖是模塊結(jié)構(gòu)圖從模塊結(jié)構(gòu)圖中不難看出,后臺(tái)服務(wù)是整個(gè)應(yīng)用程序的核心,主要包含數(shù)據(jù)獲取子模塊和短信服務(wù)子模塊。數(shù)據(jù)獲取子模塊負(fù)責(zé)周期性的從Google獲取天氣信息;短信服務(wù)子模塊則負(fù)責(zé)處理接收到的服務(wù)請(qǐng)求短信,并發(fā)送包含天氣信息的短信。后臺(tái)服務(wù)由用戶界面通過Intent啟動(dòng),啟動(dòng)后的后臺(tái)服務(wù)可以在用戶界面關(guān)閉后仍然保持運(yùn)行狀態(tài),直到用戶通過用戶界面發(fā)送Intent停止服務(wù),或系統(tǒng)因資源不足而強(qiáng)行關(guān)閉服務(wù)。用戶界面從后臺(tái)服務(wù)獲取天氣信息,而沒有直接通過網(wǎng)絡(luò)訪問Google的天氣數(shù)據(jù)。一方面是因?yàn)楹笈_(tái)服務(wù)使用了工作線程,通過后臺(tái)服務(wù)獲取天氣數(shù)據(jù)可以避免因網(wǎng)絡(luò)通信不暢造成界面失去響應(yīng)。另一方面,在用戶關(guān)閉界面后,后臺(tái)服務(wù)仍然需要更新天氣信息,以保證短信服務(wù)數(shù)據(jù)的準(zhǔn)確性。用戶界面通過直接調(diào)用數(shù)據(jù)庫(kù)適配器,向SQLite數(shù)據(jù)庫(kù)中讀寫配置信息,或?qū)MS短信服務(wù)信息進(jìn)行操作。短信監(jiān)聽器是一個(gè)BroadcastReceiver,監(jiān)視所有接收到的短信。如果短信中包含用戶自定義的關(guān)鍵字,短信監(jiān)聽器則會(huì)認(rèn)為這條短信是天氣服務(wù)請(qǐng)求短信,將短信的相關(guān)信息寫入后臺(tái)服務(wù)的短信服務(wù)隊(duì)列。如果用戶在配置信息中選擇無需提供短信服務(wù),短信監(jiān)聽器仍然繼續(xù)監(jiān)聽所有短信,只是后臺(tái)服務(wù)不再允許將服務(wù)請(qǐng)求短信寫入服務(wù)隊(duì)列。數(shù)據(jù)庫(kù)適配器封裝了所有對(duì)SQLite數(shù)據(jù)庫(kù)操作的方法,用戶界面和后臺(tái)服務(wù)會(huì)調(diào)用它實(shí)現(xiàn)數(shù)據(jù)庫(kù)操作。項(xiàng)目功能描述系統(tǒng)主要功能本軟件要完成在android手機(jī)上實(shí)現(xiàn)天氣的即時(shí)預(yù)報(bào)。所涉及的功能有:1.啟動(dòng)程序后可以進(jìn)行城市、更新頻率的設(shè)置;2.可以通過圖片和文字顯示當(dāng)前和未來的天氣狀況,包括溫度、濕度、風(fēng)向和雨雪情況等。使用效果圖實(shí)現(xiàn)與相應(yīng)天氣的結(jié)合。3.這些天氣數(shù)據(jù)是通過后臺(tái)服務(wù)獲取的,這個(gè)后臺(tái)服務(wù)可以按照一定的時(shí)間間隔,通過Google提供的公共接口獲取天氣預(yù)報(bào)信息,并將天氣信息保存在本地?cái)?shù)據(jù)庫(kù)中。二.工程結(jié)構(gòu)在程序開發(fā)階段,首先確定“天氣預(yù)報(bào)軟件”的工程名稱為WeatherDemo,包名稱為edu.hrbeu.WeatherDemo。然后根據(jù)程序模塊設(shè)計(jì)的內(nèi)容,建立WeatherDemo示例,WeatherDemo示例源代碼的文件結(jié)構(gòu):為了使源代碼文件的結(jié)構(gòu)更加清晰,WeatherDemo示例設(shè)置了多個(gè)命名空間中,分別用來保存用戶界面、數(shù)據(jù)庫(kù)、后臺(tái)服務(wù)、SMS短信和天氣數(shù)據(jù)的源代碼文件WeatherDemo示例的命名空間WeatherDemo示例將不同用途的源代碼文件放置在不同的命名空間中WeatherDemo示例的文件用途說明Android資源文件保存在/res的子目錄中。/res/drawable目錄中保存的是圖像文件,/res/layout目錄中保存的是布局文件,/res/values目錄中保存的是用來定義字符串和顏色的文件,/res/xml目錄保存的是XML格式的數(shù)據(jù)文件。所有在程序開發(fā)階段可以被調(diào)用的資源都保存在這些目錄中。資源文件名稱與用途:三.?dāng)?shù)據(jù)庫(kù)適配器數(shù)據(jù)庫(kù)適配器是最底層的模塊,主要用于封裝用戶界面和后臺(tái)服務(wù)對(duì)SQLite數(shù)據(jù)庫(kù)的操作。數(shù)據(jù)庫(kù)適配器的核心代碼主要在DBAdapter.java文件中用戶保存配置信息的類文件Config.javaConfig.java文件的全部代碼如下:1packageedu.hrbeu.WeatherDemo.DB;23publicclassConfig{4publicstaticStringCityName;5publicstaticStringRefreshSpeed;6publicstaticStringProvideSmsService;7publicstaticStringSaveSmsInfo;8publicstaticStringKeyWord;910publicstaticvoidLoadDefaultConfig(){11CityName="NewYork";12RefreshSpeed="60";13ProvideSmsService="true";14SaveSmsInfo="true";15KeyWord="NY";16}17}從代碼中不難看出,公有靜態(tài)屬性CityName、RefreshSpeed、ProvideSmsService、SaveSmsInfo和KeyWord,完全對(duì)應(yīng)數(shù)據(jù)庫(kù)中保存配置信息表的屬性(參照表12.1)。在程序啟動(dòng)后,保存在數(shù)據(jù)庫(kù)中的城市名稱、更新頻率、是否提供短信服務(wù)、是否保存短信信息和關(guān)鍵字等內(nèi)容,將被讀取到這個(gè)Config類中,供其它模塊做邏輯判斷時(shí)使用。代碼第10行的LoadDefaultConfig()函數(shù),保存了程序內(nèi)置的配置參數(shù)此函數(shù)會(huì)在兩個(gè)情況下被調(diào)用,用戶主動(dòng)選擇“恢復(fù)缺省設(shè)置”;首次啟動(dòng)程序時(shí),用來初始化保存配置參數(shù)的數(shù)據(jù)庫(kù),DBAdapter類與以往介紹過的數(shù)據(jù)庫(kù)適配器類相似,都具有繼承SQLiteOpenHelper的幫助類DBOpenHelper。DBOpenHelper在建立數(shù)據(jù)庫(kù)時(shí),同時(shí)建立兩個(gè)數(shù)據(jù)庫(kù)表,并對(duì)保存配置信息的表進(jìn)行了初始化。在DBAdapter類中,用戶界面會(huì)調(diào)用SaveConfig()和LoadConfig(),從SQLite數(shù)據(jù)庫(kù)中保存和讀取配置信息。保存配置信息時(shí),SaveConfig()函數(shù)會(huì)將Config類中的公有靜態(tài)屬性寫入數(shù)據(jù)庫(kù);反之,LoadConfig()會(huì)將數(shù)據(jù)庫(kù)中的配置信息寫入Config類中的公有靜態(tài)屬性。另一個(gè)會(huì)調(diào)用DBAdapter類的是后臺(tái)服務(wù),即WeatherService類。后臺(tái)服務(wù)主要調(diào)用SaveOneSms(SimpleSmssms)、DeleteAllSms()和GetAllSms()函數(shù),分別用來保存SMS短信記錄、刪除所有SMS數(shù)據(jù)記錄和獲取所有SMS數(shù)據(jù)記錄。在GetAllSms()函數(shù)中,調(diào)用了一個(gè)私有函數(shù)ToSimpleSms(Cursorcursor),用來將從數(shù)據(jù)庫(kù)獲取的數(shù)據(jù)轉(zhuǎn)換為SimpleSms實(shí)例數(shù)組。四.短信監(jiān)聽器短信監(jiān)聽器本質(zhì)上是BroadcastReceiver,用于監(jiān)聽Android系統(tǒng)所接收到的所有SMS短消息,可以在應(yīng)用程序關(guān)閉后仍然繼續(xù)運(yùn)行,核心代碼在SmsReceiver.java文件中。在介紹SmsReceiver類前,先說明用來保存SMS短信內(nèi)容和相關(guān)信息的SimpleSms類。android.telephony.SmsMessage是Android提供的短信類,但這里需要一個(gè)更精簡(jiǎn)、小巧的類,保存少量的信息,因此構(gòu)造了SimpleSms類,僅用來保存短信的發(fā)送者、內(nèi)容、接收時(shí)間和返回結(jié)果。這里的“返回結(jié)果”指的是返回包含天氣信息的短信內(nèi)容。SimpleSms.java文件完整代碼:1packageedu.hrbeu.WeatherDemo.SMS;2importjava.text.SimpleDateFormat;34publicclassSimpleSms{5publicStringSender;6publicStringBody;7publicStringReceiveTime;8publicStringReturnResult;910publicSimpleSms(){11}12publicSimpleSms(Stringsender,Stringbody){13this.Sender=sender;14this.Body=body;15SimpleDateFormattempDate=newSimpleDateFormat("yyyy-MM-dd"+""+"hh:mm:ss");16this.ReceiveTime=tempDate.format(newjava.util.Date());17this.ReturnResult="";18}19}代碼第5行到第8行的屬性Sender、Body、ReceiveTime和ReturnResult,分別表示SMS短信的發(fā)送者、內(nèi)容、接收時(shí)間和返回結(jié)果。第15行和第16行在SimpleSms類的構(gòu)造函數(shù)中,直接將系統(tǒng)時(shí)間以“年-月-日小時(shí):分:秒”的格式保存在ReceiveTime屬性中。SmsReceiver類繼承BroadcastReceiver,重載了onReceive()函數(shù)。系統(tǒng)消息的識(shí)別和關(guān)鍵字的識(shí)別并不復(fù)雜,只要接收vider.Telephony.SMS_RECEIVED類型的系統(tǒng)消息,則表明是Android系統(tǒng)接收到了短信。將短信的內(nèi)容拆分后,判斷消息內(nèi)容是否包含用戶定義的關(guān)鍵字,則可判斷該短信是否為天氣服務(wù)請(qǐng)求短信。最后,在AndroidManifest.xml文件中注冊(cè)短信監(jiān)聽器SmsReceiver,并聲明可接收短信的用戶許可android.permission.RECEIVE_SMS。如果注冊(cè)的組件不在根命名空間中,則需要將子命名空間寫在類的前面,例如下面在代碼第1行中,因?yàn)镾msReceiver.java文件在edu.hrbeu.WeatherDemo.Service命名空間下,而不在根命名空間edu.hrbeu.WeatherDemo下,因此注冊(cè)組件時(shí)需要在類名SmsReceiver前添加.Service。1<receiverandroid:name=".Service.SmsReceiver">2<intent-filter>3<actionandroid:name="vider.Telephony.SMS_RECEIVED"/>4</intent-filter>5</receiver>6<uses-permissionandroid:name="android.permission.RECEIVE_SMS"/>五.后臺(tái)服務(wù)后臺(tái)服務(wù)是WeatherDemo示例的核心模塊,在用戶啟動(dòng)后持續(xù)在后臺(tái)運(yùn)行,直到用戶手動(dòng)停止服務(wù),后臺(tái)服務(wù)功能,發(fā)送包含天氣信息的SMS短信(短信發(fā)送子模塊,周期性的獲取Google的天氣數(shù)據(jù)(數(shù)據(jù)獲取子模塊)。短信發(fā)送子模塊后臺(tái)服務(wù)在單獨(dú)的線程上運(yùn)行,首先調(diào)用ProcessSmsList()函數(shù),檢查短信隊(duì)列中是否有需要回復(fù)的短信,然后調(diào)用GetGoogleWeatherData()函數(shù)獲取天氣數(shù)據(jù),最后線程暫停1秒,以釋放CPU資源,WeatherDemo示例后臺(tái)服務(wù)的核心代碼在WeatherService.java文件中。下面是線程調(diào)用函數(shù)的部分代碼:privatestaticArrayList<SimpleSms>smsList=newArrayList<SimpleSms>();23privateRunnablebackgroudWork=newRunnable(){4@Override5publicvoidrun(){6try{7while(!Terrupted()){8ProcessSmsList();9GetGoogleWeatherData();10Thread.sleep(1000);11}12}catch(InterruptedExceptione){13e.printStackTrace();14}15}16};ProcessSmsList()函數(shù)用來檢查短信列表smsList,并根據(jù)Weather類中保存的天氣數(shù)據(jù),向請(qǐng)求者的發(fā)送回復(fù)。WeatherService.java文件的ProcessSmsList()函數(shù)代碼如下。privatevoidProcessSmsList(){2if(smsList.size()==0){3return;4}5SmsManagersmsManager=SmsManager.getDefault();6PendingIntentmPi=PendingIntent.getBroadcast(this,0,newIntent(),0);7while(smsList.size()>0){8SimpleSmssms=smsList.get(0);9smsList.remove(0);10smsManager.sendTextMessage(sms.Sender,null,Weather.GetSmsMsg(),mPi,null);11sms.ReturnResult=Weather.GetSmsMsg();12SaveSmsData(sms);13}14}發(fā)送短信是使用SmsManager對(duì)象的sendTextMessage()方法,該方法一共需要5個(gè)參數(shù),第1個(gè)參數(shù)是收件人地址,第2個(gè)參數(shù)是發(fā)件人地址,第3個(gè)參數(shù)是短信正文,第4個(gè)參數(shù)是發(fā)送服務(wù),第5個(gè)參數(shù)是送達(dá)服。sendTextMessage()方法的收件人地址和短信正文是不可為空的參數(shù),而且一般GSM規(guī)范要求短信內(nèi)容要控制在70個(gè)漢字以內(nèi)。代碼第8行的Weather.GetSmsMsg(),用來獲得供回復(fù)短信使用的天氣信息,因?yàn)榭紤]到短信的字?jǐn)?shù)限制,僅返回當(dāng)天和未來一天的天氣狀況。數(shù)據(jù)獲取模塊天氣數(shù)據(jù)是從Google提供的WebService中獲取的,調(diào)試WeatherDemo示例時(shí)需要網(wǎng)絡(luò)環(huán)境,數(shù)據(jù)的獲取地址是/ig/api?hl=en&weather=New%20York。New%20York表示獲取紐約(NewYork)的天氣數(shù)據(jù),%20表示一個(gè)空格。讀者可以將上面提供的地址輸入到Web瀏覽器,在瀏覽器中直接看到XML格式的天氣數(shù)據(jù)。WeatherAdapter類實(shí)現(xiàn)了利用URL獲取位圖的私有函數(shù)GetURLBitmap(),以及用來下載和解析XML數(shù)據(jù)的公有函數(shù)GetWeatherData()。后臺(tái)服務(wù)在調(diào)用GetWeatherData()函數(shù)解析Google提供的天氣數(shù)據(jù)時(shí),會(huì)不斷調(diào)用GetURLBitmap()函數(shù),將XML數(shù)據(jù)中的天氣圖標(biāo)根據(jù)圖標(biāo)地址下載到本地保存。GetURLBitmap()函數(shù)的代碼如下:privatestaticBitmapGetURLBitmap(StringurlString){2URLurl=null;3Bitmapbitmap=null;4try{5url=newURL(""+urlString);6}7catch(MalformedURLExceptione){8e.printStackTrace();9}1011try{12HttpURLConnectionconn=(HttpURLConnection)url.openConnection();13conn.connect();14InputStreamis=conn.getInputStream();bitmap=BitmapFactory.decodeStream(is);16is.close();17}catch(IOExceptione){18e.printStackTrace();19}20returnbitmap;21}第12行代碼構(gòu)造了支持HTTP功能的URLConnection,第14行返回字節(jié)流,第15行使用字節(jié)流產(chǎn)生位圖,第16行關(guān)閉字節(jié)流。GetWeatherData()函數(shù)首先根據(jù)指定的URL地址,從網(wǎng)絡(luò)獲取字節(jié)流數(shù)據(jù),然后調(diào)用輕量級(jí)XML解析器XmlPullParser對(duì)天氣數(shù)據(jù)進(jìn)行解析,并將解析結(jié)果保存在Weather類的公有靜態(tài)屬性中。六.用戶界面在用戶界面設(shè)計(jì)上,采用可多分頁(yè)快速切換的TabHost控件。WeatherDemo示例TabHost控件的每個(gè)標(biāo)簽頁(yè)與一個(gè)Activity相關(guān)聯(lián),這樣就可以將不同標(biāo)簽頁(yè)的代碼放在不同的文件中,而且每個(gè)標(biāo)簽頁(yè)都可以有獨(dú)立的選項(xiàng)菜單。WeatherDemo類是繼承TabActivity的Tab標(biāo)簽頁(yè),共設(shè)置3個(gè)標(biāo)簽頁(yè)TAB1的標(biāo)題為“天氣預(yù)報(bào)”,關(guān)聯(lián)的Activity為WeatherActivity,TAB2的標(biāo)題為“歷史數(shù)據(jù)”,關(guān)聯(lián)Activity為HistoryActivity,TAB2的標(biāo)題為“系統(tǒng)設(shè)置”,關(guān)聯(lián)Activity為SetupActivity。WeatherDemo.java中的代碼只是用戶界面的框架,設(shè)置了Tab標(biāo)簽頁(yè)的圖標(biāo)、標(biāo)題和所關(guān)聯(lián)的Activity,標(biāo)簽頁(yè)中的具體顯示內(nèi)容還要依賴于每個(gè)Activity所設(shè)置的界面布局界面布局包含WeatherActivity、HistoryActivity、SetupActivity1.WeatherActivity用戶界面WeatherActivity在啟動(dòng)時(shí)并不能直接顯示最新的天氣信息,用戶需要通過選項(xiàng)菜單的“啟動(dòng)服務(wù)”開啟后臺(tái)服務(wù),然后點(diǎn)擊“刷新”獲取最新的天氣狀況。選項(xiàng)菜單還提供“停止服務(wù)”和“退出”選項(xiàng)。WeatherActivity使用的布局文件是tab_weather.xml,這是個(gè)較為繁瑣的界面布局,多次使用了垂直和水平的線性布局。2.historyActivity界面HistoryActivity主要用來顯示SQLite數(shù)據(jù)庫(kù)中的短信服務(wù)信息,顯示的內(nèi)容包括發(fā)送者的手機(jī)號(hào)碼、時(shí)間和回復(fù)短信內(nèi)容。為了能夠以列表的形式顯示多行數(shù)據(jù),并且定制每行數(shù)據(jù)的顯示布局,這里使用了以往章節(jié)沒有介紹過的ListActivity(Android.app.ListActivity)。ListActivity可以不通過setContentView()設(shè)置布局,也不必重載onCreate()函數(shù),而直接將顯示列表加載到ListActivity,增加了使用的便利性。在WeatherDemo示例中,仍然使用setContentView()設(shè)置布局,這樣做的好處是可以在界面中設(shè)置更為復(fù)雜的顯示元素,例如在列表上方增加了提示信息“SQLite數(shù)據(jù)庫(kù)中的短信服務(wù)信息”。下方的代碼是HistoryActivity.java文件的onCreate()函數(shù)中的設(shè)置布局和加載適配器的關(guān)鍵代碼。setContentView(R.layout.tab_history);2setListAdapter(dataAdapter);3.SetupActivity界面SetupActivity主要用來保存和恢復(fù)用戶設(shè)置的運(yùn)行參數(shù),第一次啟動(dòng)或恢復(fù)缺省設(shè)置(在選項(xiàng)菜單中)后,界面上會(huì)顯示系統(tǒng)的缺省設(shè)置,包括城市名稱、更新頻率、是否提供短信服務(wù)、是否記錄短信服務(wù)數(shù)據(jù)信息和短信服務(wù)的關(guān)鍵字。SetupActivity.java文件中,主要功能集中在RestoreDefaultSetup()、UpdateUI()和SaveConfig()三個(gè)函數(shù)上。RestoreDefaultSetup()用來恢復(fù)系統(tǒng)的缺省配置;UpdateUI()會(huì)根據(jù)保存在Config類中的數(shù)據(jù)更新SetupActivity的界面控件,SaveConfig()根據(jù)界面配置更改Config類,然后調(diào)用數(shù)據(jù)庫(kù)適配器的DBAdapter.SaveConfig()函數(shù),將Config類中的配置數(shù)據(jù)寫入數(shù)據(jù)庫(kù)??偨Y(jié)經(jīng)過幾個(gè)星期的努力,Android手機(jī)天氣預(yù)報(bào)軟件終于完成了。一開始對(duì)于如何寫出這個(gè)項(xiàng)目并沒有什么頭緒,到最后一直不斷摸索著完成了這個(gè)軟件。在這個(gè)過程中,我學(xué)會(huì)了很多知識(shí),比如Android環(huán)境的搭建、Activity、Service、ContentProvider、SQLite的用法等,但我學(xué)會(huì)的最重要的一點(diǎn)是,利用現(xiàn)有的資源去解決問題,在圖書館、網(wǎng)絡(luò)上尋找答案。雖然,這個(gè)軟件目前運(yùn)行良好,但是我認(rèn)為代碼的健壯性還很差,在整個(gè)工程的構(gòu)思方面也不足,用戶操作界面還不夠靈活,這些問題還需要今后逐一解決??傊?,通過該項(xiàng)目的實(shí)戰(zhàn)演練讓我受益匪淺,對(duì)我以后在軟件開發(fā)行業(yè)中的發(fā)展有很大的幫助。同時(shí)也讓我更有信心在軟件行業(yè)中走下去!附錄資料:不需要的可以自行刪除C語(yǔ)言中如何獲取時(shí)間?精度如何?1使用time_ttime(time_t*timer)精確到秒2使用clock_tclock()得到的是CPU時(shí)間精確到1/CLOCKS_PER_SEC秒3計(jì)算時(shí)間差使用doubledifftime(time_ttimer1,time_ttimer0)4使用DWORDGetTickCount()精確到毫秒5如果使用MFC的CTime類,可以用CTime::GetCurrentTime()精確到秒6要獲取高精度時(shí)間,可以使用BOOLQueryPerformanceFrequency(LARGE_INTEGER*lpFrequency)獲取系統(tǒng)的計(jì)數(shù)器的頻率BOOLQueryPerformanceCounter(LARGE_INTEGER*lpPerformanceCount)獲取計(jì)數(shù)器的值然后用兩次計(jì)數(shù)器的差除以Frequency就得到時(shí)間。7MultimediaTimerFunctionsThefollowingfunctionsareusedwithmultimediatimers.timeBeginPeriod/timeEndPeriod/timeGetDevCaps/timeGetSystemTime//*********************************************************************//用標(biāo)準(zhǔn)C實(shí)現(xiàn)獲取當(dāng)前系統(tǒng)時(shí)間的函數(shù)一.time()函數(shù)time(&rawtime)函數(shù)獲取當(dāng)前時(shí)間距1970年1月1日的秒數(shù),以秒計(jì)數(shù)單位,存于rawtime中。#include"time.h"voidmain(){time_trawtime;structtm*timeinfo;time(&rawtime);timeinfo=localtime(&rawtime);printf("\007Thecurrentdate/timeis:%s",asctime(timeinfo));exit(0);}=================#include--必須的時(shí)間函數(shù)頭文件time_t--時(shí)間類型(time.h定義是typedeflongtime_t;追根溯源,time_t是long)structtm--時(shí)間結(jié)構(gòu),time.h定義如下:inttm_sec;inttm_min;inttm_hour;inttm_mday;inttm_mon;inttm_year;inttm_wday;inttm_yday;inttm_isdst;time(&rawtime);--獲取時(shí)間,以秒計(jì),從1970年1月一日起算,存于rawtimelocaltime(&rawtime);--轉(zhuǎn)為當(dāng)?shù)貢r(shí)間,tm時(shí)間結(jié)構(gòu)asctime()--轉(zhuǎn)為標(biāo)準(zhǔn)ASCII時(shí)間格式:星期月日時(shí):分:秒年-----------------------------------------------------------------------------二.clock()函數(shù),用clock()函數(shù),得到系統(tǒng)啟動(dòng)以后的毫秒級(jí)時(shí)間,然后除以CLOCKS_PER_SEC,就可以換成“秒”,標(biāo)準(zhǔn)c函數(shù)。clock_tclock(void);#includeclock_tt=clock();longsec=t/CLOCKS_PER_SEC;他是記錄時(shí)鐘周期的,實(shí)現(xiàn)看來不會(huì)很精確,需要試驗(yàn)驗(yàn)證;---------------------------------------------------------------------------三.gettime(&t);據(jù)說tc2.0的time結(jié)構(gòu)含有毫秒信息#include#includeintmain(void){structtimet;gettime(&t);printf("Thecurrenttimeis:-:d:d.d\n",t.ti_hour,t.ti_min,t.ti_sec,t.ti_hund);return0;}time是一個(gè)結(jié)構(gòu)體,,其中成員函數(shù)ti_hund是毫秒。。。--------------------------------------------------------------------------------四.GetTickCount(),這個(gè)是windows里面常用來計(jì)算程序運(yùn)行時(shí)間的函數(shù);DWORDdwStart=GetTickCount();//這里運(yùn)行你的程序代碼DWORDdwEnd=GetTickCount();則(dwEnd-dwStart)就是你的程序運(yùn)行時(shí)間,以毫秒為單位這個(gè)函數(shù)只精確到55ms,1個(gè)tick就是55ms。--------------------------------------------------------------------------------五.timeGetTime()t,imeGetTime()基本等于GetTickCount(),但是精度更高DWORDdwStart=timeGetTime();//這里運(yùn)行你的程序代碼DWORDdwEnd=timeGetTime();則(dwEnd-dwStart)就是你的程序運(yùn)行時(shí)間,以毫秒為單位雖然返回的值單位應(yīng)該是ms,但傳說精度只有10ms。=========================================//*****************************************************************Unix##unix時(shí)間相關(guān),也是標(biāo)準(zhǔn)庫(kù)的//*********************************************************************1.timegm函數(shù)只是將structtm結(jié)構(gòu)轉(zhuǎn)成time_t結(jié)構(gòu),不使用時(shí)區(qū)信息;time_ttimegm(structtm*tm);2.mktime使用時(shí)區(qū)信息time_tmktime(structtm*tm);timelocal函數(shù)是GNU擴(kuò)展的與posix函數(shù)mktime相當(dāng)time_ttimelocal(structtm*tm);3.gmtime函數(shù)只是將time_t結(jié)構(gòu)轉(zhuǎn)成structtm結(jié)構(gòu),不使用時(shí)區(qū)信息;structtm*gmtime(consttime_t*clock);4.localtime使用時(shí)區(qū)信息structtm*localtime(consttime_t*clock);1.time獲取時(shí)間,stime設(shè)置時(shí)間time_tt;t=time(&t);2.stime其參數(shù)應(yīng)該是GMT時(shí)間,根據(jù)本地時(shí)區(qū)設(shè)置為本地時(shí)間;intstime(time_t*tp)3.UTC=true表示采用夏時(shí)制;4.文件的修改時(shí)間等信息全部采用GMT時(shí)間存放,不同的系統(tǒng)在得到修改時(shí)間后通過localtime轉(zhuǎn)換成本地時(shí)間;5.設(shè)置時(shí)區(qū)推薦使用setup來設(shè)置;6.設(shè)置時(shí)區(qū)也可以先更變/etc/sysconfig/clock中的設(shè)置再將ln-fs/usr/share/zoneinfo/xxxx/xxx/etc/localtime才能重效time_t只能表示68年的范圍,即mktime只能返回1970-2038這一段范圍的time_t看看你的系統(tǒng)是否有time_t64,它能表示更大的時(shí)間范圍//***************************************************************windows##Window里面的一些不一樣的//*********************************************************************一.CTime()類VC編程一般使用CTime類獲得當(dāng)前日期和時(shí)間CTimet=GetCurrentTime();SYSTEMTIME結(jié)構(gòu)包含毫秒信息typedefstruct_SYSTEMTIME{WORDwYear;WORDwMonth;WORDwDayOfWeek;WORDwDay;WORDwHour;WORDwMinute;WORDwSecond;WORDwMilliseconds;}SYSTEMTIME,*PSYSTEMTIME;SYSTEMTIMEt1;GetSystemTime(&t1)CTimecurTime(t1);WORDms=t1.wMilliseconds;SYSTEMTIMEsysTm;::GetLocalTime(&sysTm);在time.h中的_strtime()//只能在windows中用chart[11];_strtime(t);puts(t);//*****************************獲得當(dāng)前日期和時(shí)間CTimetm=CTime::GetCurrentTime();CStringstr=tm.Format("%Y-%m-%d");在VC中,我們可以借助CTime時(shí)間類,獲取系統(tǒng)當(dāng)前日期,具體使用方法如下:CTimet=CTime::GetCurrentTime();//獲取系統(tǒng)日期,存儲(chǔ)在t里面intd=t.GetDay();//獲得當(dāng)前日期inty=t.GetYear();//獲取當(dāng)前年份intm=t.GetMonth();//獲取當(dāng)前月份inth=t.GetHour();//獲取當(dāng)前為幾時(shí)intmm=t.GetMinute();//獲取當(dāng)前分鐘ints=t.GetSecond();//獲取當(dāng)前秒intw=t.GetDayOfWeek();//獲取星期幾,注意1為星期天,7為星期六二.CTimeSpan類如果想計(jì)算兩段時(shí)間的差值,可以使用CTimeSpan類,具體使用方法如下:CTimet1(1999,3,19,22,15,0);CTimet=CTime::GetCurrentTime();CTimeSpanspan=t-t1;//計(jì)算當(dāng)前系統(tǒng)時(shí)間與時(shí)間t1的間隔intiDay=span.GetDays();//獲取這段時(shí)間間隔共有多少天intiHour=span.GetTotalHours();//獲取總共有多少小時(shí)intiMin=span.GetTotalMinutes();//獲取總共有多少分鐘intiSec=span.GetTotalSeconds();//獲取總共有多少秒------------------------------------------------------------------------------三._timeb()函數(shù)_timeb定義在SYS\TIMEB.H,有四個(gè)fieldsdstflagmillitmtimetimezonevoid_ftime(struct_timeb*timeptr);struct_timebtimebuffer;_ftime(&timebuffer);取當(dāng)前時(shí)間:文檔講可以到ms,有人測(cè)試,好象只能到16ms!四.設(shè)置計(jì)時(shí)器定義TIMERID#defineTIMERID_JISUANFANGSHI2在適當(dāng)?shù)牡胤皆O(shè)置時(shí)鐘,需要開始其作用的地方;SetTimer(TIMERID_JISUANFANGSHI,200,NULL);在不需要定時(shí)器的時(shí)候的時(shí)候銷毀掉時(shí)鐘KillTimer(TIMERID_JISUANFANGSHI);對(duì)應(yīng)VC程序的消息映射voidCJisuan::OnTimer(UINTnIDEvent){switch(nIDEvent)}---------------------------------------------------------------------------------------##如何設(shè)定當(dāng)前系統(tǒng)時(shí)間---------------------------------------windowsSYSTEMTIMEm_myLocalTime,*lpSystemTime;m_myLocalTime.wYear=2003;m_myLocalTime.wM;m_myLocalTime.wDay=1;m_myLocalTime.wHour=0;m_myLocalTime.wMinute=0;m_myLocalTime.wSec;m_myLocalTime.wMillisec;lpSystemTime=&m_myLocalTime;if(SetLocalTime(lpSystemTime))//此處換成SetSystemTime()也不行MessageBox("OK!");elseMessageBox("Error!");SYSTEMTIMEm_myLocalTime,*lpSystemTime;m_myLocalTime.wYear=2003;m_myLocalTime.wM;m_myLocalTime.wDay=1;lpSystemTime=&m_myLocalTime;if(SetDate(lpSystemTime))//此處換成SetSystemTime()也不行MessageBox("OK!");elseMessageBox("Error!");本文來自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:/khuang2008/archive/2008/12/09/3483274.aspx一種制作微秒級(jí)精度定時(shí)器的方法當(dāng)使用定時(shí)器時(shí),在很多情況下只用到毫秒級(jí)的時(shí)間間隔,所以只需用到下面的兩種常用方式就滿足要求了。一是用SetTimer函數(shù)建立一個(gè)定時(shí)器后,在程序中通過處理由定時(shí)器發(fā)送到線程消息隊(duì)列中的WM_TIMER消息,而得到定時(shí)的效果(退出程序時(shí)別忘了調(diào)用和SetTimer配對(duì)使用的KillTimer函數(shù))。二是利用GetTickCount函數(shù)可以返回自計(jì)算機(jī)啟動(dòng)后的時(shí)間,通過兩次調(diào)用GetTickCount函數(shù),然后控制它們的差值來取得定時(shí)效果,此方式跟第一種方式一樣,精度也是毫秒級(jí)的。用這兩種方式取得的定時(shí)效果雖然在許多場(chǎng)合已經(jīng)滿足實(shí)際的要求,但由于它們的精度只有毫秒級(jí)的,而且在要求定時(shí)時(shí)間間隔小時(shí),實(shí)際定時(shí)誤差大。下面介紹一種能取得高精度定時(shí)的方法。在一些計(jì)算機(jī)硬件系統(tǒng)中,包含有高精度運(yùn)行計(jì)數(shù)器(high-resolutionperformancecounter),利用它可以獲得高精度定時(shí)間隔,其精度與CPU的時(shí)鐘頻率有關(guān)。采用這種方法的步驟如下:1、首先調(diào)用QueryPerformanceFrequency函數(shù)取得高精度運(yùn)行計(jì)數(shù)器的頻率f。單位是每秒多少次(n/s),此數(shù)一般很大。2、在需要定時(shí)的代碼的兩端分別調(diào)用QueryPerformanceCounter以取得高精度運(yùn)行計(jì)數(shù)器的數(shù)值n1,n2。兩次數(shù)值的差值通過f換算成時(shí)間間隔,t=(n2-n1)/f。下面舉一個(gè)例子來演示這種方法的使用及它的精確度。在VC6.0下用MFC建立一個(gè)對(duì)話框工程,取名為HightTimer.在對(duì)話框面板中控件的布局如下圖:其中包含兩個(gè)靜態(tài)文本框,兩個(gè)編輯框和兩個(gè)按紐。上面和下面位置的編輯框的ID分別為IDC_E_TEST和IDC_E_ACTUAL,通過MFCClassWizard添加的成員變量也分別對(duì)應(yīng)為DWORDm_dwTest和DWORDm_dwAct.“退出”按紐的ID為IDOK,“開始測(cè)試”按紐ID為IDC_B_TEST,用MFCClassWizard添加此按紐的單擊消息處理函數(shù)如下:voidCHightTimerDlg::OnBTest(){//TODO:AddyourcontrolnotificationhandlercodehereUpdateData(TRUE);//取輸入的測(cè)試時(shí)間值到與編輯框相關(guān)聯(lián)的成員變量m_dwTest中LARGE_INTEGERfrequence;if(!QueryPerformanceFrequency(&frequence))//取高精度運(yùn)行計(jì)數(shù)器的頻率,若硬件不支持則返回FALSEMessageBox("Yourcomputerhardwaredoesn'tsupportthehigh-resolutionperformancecounter","NotSupport",MB_ICONEXCLAMATION|MB_OK);LARGE_INTEGERtest,ret;test.QuadPart=frequence.QuadPart*m_dwTest/1000000;//通過頻率換算微秒數(shù)到對(duì)應(yīng)的數(shù)量(與CPU時(shí)鐘有關(guān)),1秒=1000000微秒ret=MySleep(test);//調(diào)用此函數(shù)開始延時(shí),返回實(shí)際花銷的數(shù)量m_dwAct=(DWORD)(1000000*ret.QuadPart/frequence.QuadPart);//換算到微秒數(shù)UpdateData(FALSE);//顯示到對(duì)話框面板}其中上面調(diào)用的MySleep函數(shù)如下:LARGE_INTEGERCHightTimerDlg::MySleep(LARGE_INTEGERInterval)///////////////////////////////////////////////////////////////////////////////////////////////////////////////功能:執(zhí)行實(shí)際的延時(shí)功能
//參數(shù):Interval參數(shù)為需要執(zhí)行的延時(shí)與時(shí)間有關(guān)的數(shù)量
//返回值:返回此函數(shù)執(zhí)行后實(shí)際所用的時(shí)間有關(guān)的數(shù)量
///////////////////////////////////////////////////////////////////////////////////////////////////////////{LARGE_INTEGERprivious,current,Elapse;QueryPerformanceCounter(&privious);current=privious;while(current.QuadPart-privious.QuadPart<Interval.QuadPart)QueryPerformanceCounter(¤t);Elapse.QuadPart=current.QuadPart-privious.QuadPart;returnElapse;}注:別忘了在頭文件中為此函數(shù)添加函數(shù)聲明。至此,可以編譯和執(zhí)行此工程了,結(jié)果如上圖所示。在本人所用的機(jī)上(奔騰366,64M內(nèi)存)測(cè)試,當(dāng)測(cè)試時(shí)間超過3微秒時(shí),準(zhǔn)確度已經(jīng)非常高了,此時(shí)機(jī)器執(zhí)行本身延時(shí)函數(shù)代碼的時(shí)間對(duì)需要延時(shí)的時(shí)間影響很小了。上面的函數(shù)由于演示測(cè)試的需要,沒有在函數(shù)級(jí)封裝,下面給出的函數(shù)基本上可以以全局函數(shù)的形式照搬到別的程序中。BOOLMySleep(DWORDdwInterval)///////////////////////////////////////////////////////////////////////////////////////////////////////////////功能:執(zhí)行微秒級(jí)的延時(shí)功能
//參數(shù):Interval參數(shù)為需要的延時(shí)數(shù)(單位:微秒)
//返回值:若計(jì)算機(jī)硬件不支持此功能,返回FALSE,若函數(shù)執(zhí)行成功,返回TRUE
///////////////////////////////////////////////////////////////////////////////////////////////////////////{BOOLbNormal=TRUE;LARGE_INTEGERfrequence,privious,current,interval;if(!QueryPerformanceFrequency(&frequence)){::MessageBox(NULL,"Yourcomputerhardwaredoesn'tsupportthehigh-resolutionperformancecounter","NotSupport",MB_ICONEXCLAMATION|MB_OK);//或其它的提示信息returnFALSE;}interval.QuadPart=frequence.QuadPart*dwInterval/1000000;bNormal=bNormal&&QueryPerformanceCounter(&privious);current=privious;while(current.QuadPart-privious.QuadPart<interval.QuadPart)bNormal=bNormal&&QueryPerformanceCounter(¤t);returnbNormal;}需要指出的是,由于在此函數(shù)中的代碼很多,機(jī)器在執(zhí)行這些代碼所花費(fèi)的時(shí)間也很長(zhǎng),所以在需要幾個(gè)微秒的延時(shí)時(shí),會(huì)影響精度。實(shí)際上,讀者在熟悉這種方法后,只要使用QueryPerformanceFrequency和QueryPerformanceCounter這兩個(gè)函數(shù)就能按實(shí)際需要寫出自己的延時(shí)代碼了。使用CPU時(shí)間戳進(jìn)行高精度計(jì)時(shí)對(duì)關(guān)注性能的程序開發(fā)人員而言,一個(gè)好的計(jì)時(shí)部件既是益友,也是良師。計(jì)時(shí)器既可以作為程序組件幫助程序員精確的控制程序進(jìn)程,又是一件有力的調(diào)試武器,在有經(jīng)驗(yàn)的程序員手里可以盡快的確定程序的性能瓶頸,或者對(duì)不同的算法作出有說服力的性能比較。在Windows平臺(tái)下,常用的計(jì)時(shí)器有兩種,一種是timeGetTime多媒體計(jì)時(shí)器,它可以提供毫秒級(jí)的計(jì)時(shí)。但這個(gè)精度對(duì)很多應(yīng)用場(chǎng)合而言還是太粗糙了。另一種是QueryPerformanceCount計(jì)數(shù)器,隨系統(tǒng)的不同可以提供微秒級(jí)的計(jì)數(shù)。對(duì)于實(shí)時(shí)圖形處理、多媒體數(shù)據(jù)流處理、或者實(shí)時(shí)系統(tǒng)構(gòu)造的程序員,善用QueryPerformanceCount/QueryPerformanceFrequency是一項(xiàng)基本功。本文要介紹的,是另一種直接利用PentiumCPU內(nèi)部時(shí)間戳進(jìn)行計(jì)時(shí)的高精度計(jì)時(shí)手段。以下討論主要得益于《Windows圖形編程》一書,第15頁(yè)-17頁(yè),有興趣的讀者可以直接參考該書。關(guān)于RDTSC指令的詳細(xì)討論,可以參考Intel產(chǎn)品手冊(cè)。本文僅僅作拋磚之用。在IntelPentium以上級(jí)別的CPU中,有一個(gè)稱為“時(shí)間戳(TimeStamp)”的部件,它以64位無符號(hào)整型數(shù)的格式,記錄了自CPU上電以來所經(jīng)過的時(shí)鐘周期數(shù)。由于目前的CPU主頻都非常高,因此這個(gè)部件可以達(dá)到納秒級(jí)的計(jì)時(shí)精度。這個(gè)精確性是上述兩種方法所無法比擬的。在Pentium以上的CPU中,提供了一條機(jī)器指令RDTSC(ReadTimeStampCounter)來讀取這個(gè)時(shí)間戳的數(shù)字,并將其保存在EDX:EAX寄存器對(duì)中。由于EDX:EAX寄存器對(duì)恰好是Win32平臺(tái)下C++語(yǔ)言保存函數(shù)返回值的寄存器,所以我們可以把這條指令看成是一個(gè)普通的函數(shù)調(diào)用。像這樣:inlineunsigned__int64GetCycleCount(){__asmRDTSC}但是不行,因?yàn)镽DTSC不被C++的內(nèi)嵌匯編器直接支持,所以我們要用_emit偽指令直接嵌入該指令的機(jī)器碼形式0X0F、0X31,如下:inlineunsigned__int64GetCycleCount()
{
__asm_emit0x0F
__asm_emit0x31
}
以后在需要計(jì)數(shù)器的場(chǎng)合,可以像使用普通的Win32API一樣,調(diào)用兩次GetCycleCount函數(shù),比較兩個(gè)返回值的差,像這樣:
unsignedlongt;
t=(unsignedlong)GetCycleCount();
//DoSomethingtime-intensive...
t-=(unsignedlong)GetCycleCount();
《Windows圖形編程》第15頁(yè)編寫了一個(gè)類,把這個(gè)計(jì)數(shù)器封裝起來。有興趣的讀者可以去參考那個(gè)類的代碼。作者為了更精確的定時(shí),做了一點(diǎn)小小的改進(jìn),把執(zhí)行RDTSC指令的時(shí)間,通過連續(xù)兩次調(diào)用GetCycleCount函數(shù)計(jì)算出來并保存了起來,以后每次計(jì)時(shí)結(jié)束后,都從實(shí)際得到的計(jì)數(shù)中減掉這一小段時(shí)間,以得到更準(zhǔn)確的計(jì)時(shí)數(shù)字。但我個(gè)人覺得這一點(diǎn)點(diǎn)改進(jìn)意義不大。在我的機(jī)器上實(shí)測(cè),這條指令大概花掉了幾十到100多個(gè)周期,在Celeron800MHz的機(jī)器上,這不過是十分之一微秒的時(shí)間。對(duì)大多數(shù)應(yīng)用來說,這點(diǎn)時(shí)間完全可以忽略不計(jì);而對(duì)那些確實(shí)要精確到納秒數(shù)量級(jí)的應(yīng)用來說,這個(gè)補(bǔ)償也過于粗糙了。
這個(gè)方法的優(yōu)點(diǎn)是:
1.高精度??梢灾苯舆_(dá)到納秒級(jí)的計(jì)時(shí)精度(在1GHz的CPU上每個(gè)時(shí)鐘周期就是一納秒),這是其他計(jì)時(shí)方法所難以企及的。
2.成本低。timeGetTime函數(shù)需要鏈接多媒體庫(kù)winmm.lib,QueryPerformance*函數(shù)根據(jù)MSDN的說明,需要硬
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年專利許可合同:某企業(yè)使用某專利技術(shù)
- 2024年建筑勞務(wù)隊(duì)安全生產(chǎn)協(xié)議
- 2024年度智能家居系統(tǒng)采購(gòu)合同
- 2024年度城市基礎(chǔ)設(shè)施建設(shè)與管理協(xié)議
- 2024證券投資基金基金合同范例
- 2024年國(guó)際石油天然氣開采銷售合同
- 2024醫(yī)療耗材生產(chǎn)原料采購(gòu)與供應(yīng)合同
- 2024年創(chuàng)新型企業(yè)孵化合作框架協(xié)議
- 保安員述職報(bào)告范文(7篇)
- 2024年度項(xiàng)目融資合同融資金額及還款方式
- 學(xué)前教育論文范文8000字(通用九篇)
- 小學(xué)數(shù)學(xué)北師大五年級(jí)上冊(cè)數(shù)學(xué)好玩 圖形中的規(guī)律-
- 《富饒的西沙群島》說課稿(優(yōu)秀3篇)
- 墓碑碑文范文(通用十四篇)
- 大象版一年級(jí)科學(xué)上冊(cè)全冊(cè)教案
- 5000字論文范文(推薦十篇)
- 教案評(píng)分標(biāo)準(zhǔn)
- 中藥飲片處方點(diǎn)評(píng)表
- 《節(jié)能監(jiān)察的概念及其作用》
- 綜合布線系統(tǒng)竣工驗(yàn)收表
- 蔬菜會(huì)員卡策劃營(yíng)銷推廣方案多篇
評(píng)論
0/150
提交評(píng)論