安卓開發(fā)技巧總匯第二章_第1頁
安卓開發(fā)技巧總匯第二章_第2頁
安卓開發(fā)技巧總匯第二章_第3頁
安卓開發(fā)技巧總匯第二章_第4頁
安卓開發(fā)技巧總匯第二章_第5頁
已閱讀5頁,還剩55頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、1.Activity21. Activity的生命周期【簡介】22Activity 的創(chuàng)建23Actvity 堆棧3Intent對象調(diào)用Activity實(shí)例42. Context menus for expandablelists63. Android自動(dòng)化測試初探81:捕獲Activity上的Element82: Hierarchyviewer 捕獲Element的123: 架構(gòu)實(shí)現(xiàn)144:模擬鍵盤鼠標(biāo)事件(Socket+Instrumentation實(shí)現(xiàn))155:再述模擬鍵盤鼠標(biāo)事件(adb shell 實(shí)現(xiàn))184. 背景圖片迎合不同手機(jī)分辨率的問題285. 應(yīng)用程序圖標(biāo)296. 動(dòng)態(tài)s

2、tart頁面297. 運(yùn)用java mail包實(shí)現(xiàn)發(fā)Gmail郵件33第一個(gè)類:MailSenderInfo.java33第二個(gè)類:SimpleMailSender.java35第三個(gè)類:MyAuthenticator.java38主函數(shù)代碼38注意:398. Android鍵盤響應(yīng)函數(shù)399. Vector用法4110. 線程的處理4411. Message Hander 監(jiān)聽消息4612. 顯示簡單的提示信息471. 簡單的對話框:472. tost提示信息:473. 包含兩個(gè)按鈕的對話框484. 三個(gè)按鈕的提示框495. 包含輸入的dlg(xml不完整)506. 圓形進(jìn)度框511. Ac

3、tivity1. Activity的生命周期【簡介】和其他手機(jī)平臺的應(yīng)用程序一樣,Android的應(yīng)用程序的生命周期是被統(tǒng)一掌控的,也 就是說我們寫的應(yīng)用程序命運(yùn)掌握在別人(系統(tǒng))的手里,我們不能改變它,只能學(xué)習(xí)并 適應(yīng)它。 簡單地說一下為什么是這樣:我們手機(jī)在運(yùn)行一個(gè)應(yīng)用程序的時(shí)候,有可能打進(jìn)來電話 發(fā)進(jìn)來短信,或者沒有電了,這時(shí)候程序都會(huì)被中斷,優(yōu)先去服務(wù)電話的基本功能,另 外系統(tǒng)也不允許你占用太多資源,至少要保證電話功能吧,所以資源不足的時(shí)候也就有可 能被干掉。OPhone Activity生命周期解析要為你的OPhone應(yīng)用程序創(chuàng)建用戶界面屏幕,就需要繼承Activity類,并且使用V

4、iews為你的應(yīng)用程序提供用戶交互。每個(gè)Activity表示用戶界面中的一個(gè)屏幕。你的應(yīng)用程序越復(fù)雜,需要的屏就越多,每一屏都是一個(gè)新的Activity。典型的一個(gè)應(yīng)用程序一般至少包括一個(gè)屏用來處理用戶界面的主要功能,也常常還有其他的屏用來輸入用戶信息,或者展現(xiàn)不同的數(shù)據(jù)并支持更多的功能。大多數(shù)Activity都是全屏的,但是你也可以創(chuàng)建半透明或者浮動(dòng)的Activity.理解Activity的生命周期對應(yīng)用程序開發(fā)來說是至關(guān)重要的,這樣才能確保您的應(yīng)用提供了一個(gè)很好的用戶體驗(yàn)和妥善管理其資源。由于OPhone應(yīng)用程序不控制自己的進(jìn)程壽命,由OPhone Runtime管理每個(gè)應(yīng)用程序進(jìn)程,但是

5、每個(gè)Activity的狀態(tài)反過來會(huì)影響到OPhone Runtime是否將終止當(dāng)前Activity和還是讓它繼續(xù)運(yùn)行2Activity 的創(chuàng)建通過繼承Activity類,我們可以創(chuàng)建一個(gè)新的Activity?;镜氖纠a如下所示:import android.app.Activity; import android.os.Bundle; public class MyActivity extends Activity /* Called when the activity is first created. */ Override public void onCreate(Bundle ic

6、icle) super.onCreate(icicle); Activity基類僅僅是一個(gè)封裝了一些與窗口顯示相關(guān)功能的空空的屏幕,本身并不具備太具體用處,因此創(chuàng)建Activity以后,第一件事情就是在這個(gè)空空的屏幕上擺上你所需要的物件,各種Views。你可以在xml文件中的定義你所需要的Views, 也可以在代碼中定義。通過在Acitvity onCreate方法中調(diào)用setContentView,便可將Activity與你的Views綁定在一起來實(shí)現(xiàn)用戶交互的功能。在代碼中定義你的Views Override public void onCreate(Bundle icicle) supe

7、r.onCreate(icicle); MyView myView = new MyView(this); setContentView(myView); 在layout文件中定義你的Views Override public void onCreate(Bundle icicle) super.onCreate(icicle); setContentView(R.layout.main); 為了在你的應(yīng)用程序中使用Acitvity,你還需要將你寫的Acitvity類注冊到Manifest當(dāng)中,參見以下XML片段:3Actvity 堆棧每個(gè)Actvity的狀態(tài)由它所在Activity棧中的位置

8、所決定,所有當(dāng)前正在運(yùn)行的Actvity將遵循照后進(jìn)先出的原則。當(dāng)一個(gè)新的Activity啟動(dòng),當(dāng)前的Activity將移至堆棧的頂部,如果用戶使用Back按鈕,或在前臺Activity被關(guān)閉,下一個(gè)Activity將被激活并且移至到堆棧的頂部。這個(gè)過程如下圖所示 Intent對象調(diào)用Activity實(shí)例Android中一個(gè)Activity調(diào)用另一個(gè)Activity Intent對象的使用第一步:建Android 工程:IntentDemo。第二步:編寫Activity 的子類別:IntentDemo,其程序代碼如下:package ent;import android

9、.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.widget.Button;public class IntentDemo extends Activity /* Called when the activity is first created. */ Override public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceSt

10、ate); setContentView(R.layout.main); Button btn1 = (Button) findViewById(R.id.btn1); btn1.setOnClickListener(new Button.OnClickListener() Override public void onClick(View v) / TODO Auto-generated method stub Intent intent = new Intent(); intent.setClass(IntentDemo.this, Intent2.class); /* 調(diào)用一個(gè)新的Act

11、ivity */ startActivity(intent); /* 關(guān)閉原本的Activity */ IntentDemo.this.finish(); ); 第三步:新建一個(gè)Activity 的子類別:Intent2,其程序代碼如下:package ent;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.widget.Button;public class Intent2

12、 extends Activity /* Called when the activity is first created. */ Override public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.mylayout); Button btn2 = (Button) findViewById(R.id.btn2); btn2.setOnClickListener(new Button.OnClickListener() Over

13、ride public void onClick(View v) / TODO Auto-generated method stub Intent intent = new Intent(); intent.setClass(Intent2.this, IntentDemo.class); startActivity(intent); Intent2.this.finish(); ); 第四步:修改res/layout/main.xml,其代碼如下:第五步:修改res/layout/ mylayout.xml,其代碼如下:第六步: AndroidManifest.xml中聲明activity

14、OK了!2. Context menus for expandablelistsBy steveoliverc An expandable list supports context menus in pretty much the same way that a standard list does: add a listener for the context menu (when the user has long-pressed on a list item). Unlike a standard list view, however, you probably want to kno

15、w whether the user has selected a group (expandable item) or a child (sub-item) list item.Furthermore, you might not want to do anything if the user tries to bring up a context menu on a group item. There might be cases where you would want to do something to all of the children under a group, but i

16、n my Librarium application, I wanted to ignore group items and present the context menu only for children.First, you need to know when the context menu is going to be created so that you can identify whether the user pressed on a group or a child. If they pressed on a group, then cancel the context

17、menu. This also gives us a chance to get the text of the child item, so that we can put it into the header of the context menu.public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) super.onCreateContextMenu(menu, v, menuInfo);ExpandableListView.ExpandableListContextMenuI

18、nfo info =(ExpandableListView.ExpandableListContextMenuInfo) menuInfo;int type =ExpandableListView.getPackedPositionType(info.packedPosition);int group =ExpandableListView.getPackedPositionGroup(info.packedPosition);int child =ExpandableListView.getPackedPositionChild(info.packedPosition);/Only crea

19、te a context menu for child itemsif (type = 1) /Array created earlier when we built the expandable listString page =mListStringArraygroupchild;menu.setHeaderTitle(page);menu.add(0, MENU_READ, 0, “Read page”);menu.add(0, MENU_EDIT, 0, “Edit page”);menu.add(0, MENU_FAVORITE, 0, “Add page to favorites”

20、);menu.add(0, MENU_EXPORT, 0, “Export page to file”);menu.add(0, MENU_DELETE, 1, “Delete page”);Second, create the context menu:public boolean onContextItemSelected(MenuItem menuItem) ExpandableListContextMenuInfo info =(ExpandableListContextMenuInfo) menuItem.getMenuInfo();int groupPos = 0, childPo

21、s = 0;int type = ExpandableListView.getPackedPositionType(info.packedPosition);if (type = ExpandableListView.PACKED_POSITION_TYPE_CHILD) groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition);childPos = ExpandableListView.getPackedPositionChild(info.packedPosition);/Pull values fr

22、om the array we built when we created the listString author = mListStringArraygroupPos0;String page = mListStringArraygroupPoschildPos * 3 + 1;rowId = Integer.parseInt(mListStringArraygroupPoschildPos * 3 + 3);switch (menuItem.getItemId() case MENU_READ:readNote(rowId);return true;case MENU_EDIT:edi

23、tNote(rowId);return true;/etc.default:return super.onContextItemSelected(menuItem);Thats it. Now users can long-press on an item in an expandable list, and get the context menu if its a child item.3. Android自動(dòng)化測試初探1:捕獲Activity上的Element第一部分:前言Android系統(tǒng)下應(yīng)用程序的測試現(xiàn)在應(yīng)該還算是個(gè)新的領(lǐng)域,網(wǎng)上關(guān)于這方面的資料很多都是基于白盒測試的,一般都是基于

24、JUnit框架和Android SDK中android.test等命名空間下的內(nèi)容進(jìn)行,但是有一個(gè)前提,那就是必須要有應(yīng)用程序的源代碼以提供測試接入點(diǎn),但是這在很多軟件公司中是不現(xiàn)實(shí)的。很多測試工程師做的工作是完全黑盒,基本接觸不到源代碼,白盒測試大部分也是由開發(fā)自己完成。 回顧一下Windows下的黑盒測試自動(dòng)化,先前使用的是微軟提供的基于.net framework的UI Automation自動(dòng)化測試框架(要求版本在.net framework 3.0以上,即VS.NET 2008 開發(fā)環(huán)境),對與擅長C#語言的人來說,使用起來確認(rèn)比較好用。本人也寫了基于UI Automation的輕量

25、級的自動(dòng)化框架,將在以后的博文中引出。 那在Android操作系統(tǒng)中能不能做類似于UI Automation的事情呢?不幸的是,Android的權(quán)限控制分的非常清楚,不同程序之間的數(shù)據(jù)訪問只能通過Intent,content provider類似的功能實(shí)現(xiàn)。也就是說你開發(fā)的運(yùn)行在Android中的自動(dòng)化程序想要捕獲當(dāng)前運(yùn)行的AUT (Application under Test) 界面上的控件等Element(該術(shù)語引自UI Automation,覺得翻譯成元素有點(diǎn)生硬,故不作翻譯)基本不可能,你也拿不到當(dāng)前active activity的引用(截止本文發(fā)帖為止,個(gè)人暫時(shí)沒有找到辦法獲得此引用

26、)。 無路可走了?模擬器里面不能走,外面能不能走?或許可以。第二部分:捕獲Activity上的Element 在Android的SDK中自帶了一個(gè)對自動(dòng)化測試比較有用的工具:hierarchyviewer(位于SDK的tools目錄下)。在模擬器運(yùn)行的情況下,使用該工具可以將當(dāng)前的Activity上的Element以對象樹的形式展現(xiàn)出來,每個(gè)Element所含的屬性也能一一盡顯。這有點(diǎn)像Windows上運(yùn)行的UI SPY,唯一遺憾的是不支持事件的觸發(fā)。不過沒有關(guān)系,可以想辦法繞,當(dāng)務(wù)之急是能在自行編寫的自動(dòng)化測試代碼里找到Activity上的Element。 第一個(gè)想到的辦法就是看hierar

27、chyviewer源碼,不巧,網(wǎng)上搜了一下,沒有資源。或許Google的官網(wǎng)上有,但是上不去??磥碇荒芊淳幾g了,找來XJad,暴力之。雖然反編譯出來的代碼很多地方提示缺少import,但代碼基本上是正確的??戳艘幌拢_實(shí)也知道了許多。后來在編寫代碼的過程中,確實(shí)也證明了如果想引用hierarchyviewer.jar這個(gè)包并調(diào)試,還是需要知道里面的一些設(shè)置的。 創(chuàng)建基于hierarchyviewer.jar這個(gè)包的調(diào)用,需要將它和另外兩個(gè)包,ddmlib.jar(在hierarchyviewer.jar同級目錄中有)和org-netbeans-api-visual.jar(需要下載并安裝net

28、beans,在其安裝目錄中有)一并導(dǎo)入到工程項(xiàng)目中,因?yàn)閔ierarchyviewer的實(shí)現(xiàn)依附于這兩個(gè)包。 想在代碼中獲取Activity上的Element需要進(jìn)行如下幾個(gè)步驟(如果使用過hierarchyviewer這個(gè)工具后會(huì)發(fā)現(xiàn),自動(dòng)化代碼所要寫的就是該工具上的使用步驟):1. Ensure adb running2. Set adb location(因?yàn)閔ierarchyviewer和模擬器的溝通完全是依靠adb做的,所以設(shè)定正確的adb程序的位置至關(guān)重要,本人就曾在這個(gè)問題上栽了半天多)3. Get Active Device (這個(gè)等同動(dòng)作發(fā)生在啟動(dòng)hierarchyviewe

29、r工具時(shí))4. Start View Server (等同于工具上Start Server 菜單觸發(fā)事件)5. Load Scene (等同于工具上Load View Hierarchy菜單觸發(fā)事件)6. Get Root View Node (獲得對象樹的根節(jié)點(diǎn),這個(gè)動(dòng)作在工具上點(diǎn)擊Load View Hierarchy菜單后會(huì)自動(dòng)加載)7. Get Sub View Node (獲得想要查找的View Node,這個(gè)動(dòng)作在工具上點(diǎn)擊Load View Hierarchy菜單后會(huì)自動(dòng)加載)說明:上述步驟中一些名稱實(shí)際上就是hierarchyviewer中所提供的可訪問方法名稱,如startV

30、iewServer、loadScene、rootNode等。另外View Node實(shí)際上hierarchyviewer中的一個(gè)類,表示的對象樹上的一個(gè)Element?,F(xiàn)將部分核心代碼粘貼如下:1. Set adb location System.setProperty(hierarchyviewer.adb,E: Androidandroid-sdk-windowstools);其中”hierarchyviewer.adb” 這個(gè)key是hierarchyviewer.jar中指定的,后面的value是存放Android SDK的路徑。這個(gè)目錄必須是當(dāng)前運(yùn)行的模擬器所對應(yīng)的adb的目錄,不能自

31、行使用其他目錄下adb,否則會(huì)發(fā)生adb進(jìn)程異常退出的錯(cuò)誤。2. Get Active DeviceIDevice devices = null;DeviceBridge.terminate();while(null=devices | 0=devices.length)DeviceBridge.initDebugBridge() ;/it must wait for some time, otherwise will throw exceptiontry Thread.sleep(1000); catch (InterruptedException e) e.printStackTrace(

32、);devices = DeviceBridge.getDevices() ;return devices;以上方法返回的是所有當(dāng)前運(yùn)行的Device列表3. Start View Server DeviceBridge.startViewServer(device);4. Load SceneViewHierarchyLoader.loadScene(device,Window.FOCUSED_WINDOW) ;5.Get Root View Nodevhs.getRoot() ;其中vhs是ViewHierarchyScene的實(shí)例對象6.Get Sub View Nodepublic V

33、iewNode findFirstChildrenElement(IDevice device, ViewNode entryViewNode, String elementID) ViewNode node=null; if(0!=entryViewNode.children.size() for(int i=0;i DUMP);out.write(new StringBuilder().append(DUMP -1).toString();out.newLine(); out.flush(); do String line;if (line = in.readLine() = null |

34、 DONE.equalsIgnoreCase(line) break; line = line.trim(); System.out.println(line); while (true); catch (IOException e) e.printStackTrace(); 運(yùn)行后的結(jié)果摘錄其中一部分(button5),列舉如下。注:當(dāng)前device中運(yùn)行的是2.1SDK中自帶的Calculator程序:com.android.calculator2.ColorButton43b8bee8 mText=1,5 getEllipsize()=4,null mMinWidth=1,0 mMinH

35、eight=1,0 mMeasuredWidth=2,79 mPaddingBottom=1,0 mPaddingLeft=1,0 mPaddingRight=1,0 mPaddingTop=1,0 mMeasuredHeight=2,78 mLeft=2,81 mPrivateFlags_DRAWING_CACHE_INVALID=3,0x0 mPrivateFlags_DRAWN=4,0x20 mPrivateFlags=8, mID=9,id/digit5 mRight=3,160 mScrollX=1,0 mScrollY=1,0 mTop=1,0 mBottom=2,78 mUser

36、PaddingBottom=1,0 mUserPaddingRight=1,0 mViewFlags=9, getBaseline()=2,54 getHeight()=2,78 layout_gravity=4,NONE layout_weight=3,1.0 layout_bottomMargin=1,0 layout_leftMargin=1,1 layout_rightMargin=1,0 layout_topMargin=1,0 layout_height=11,FILL_PARENT layout_width=11,FILL_PARENT getTag()=4,null getVi

37、sibility()=7,VISIBLE getWidth()=2,79 hasFocus()=5,false isClickable()=4,true isDrawingCacheEnabled()=5,false isEnabled()=4,true isFocusable()=4,true isFocusableInTouchMode()=5,false isFocused()=5,false isHapticFeedbackEnabled()=4,true isInTouchMode()=4,true isOpaque()=5,false isSelected()=5,false is

38、SoundEffectsEnabled()=4,true willNotCacheDrawing()=5,false willNotDraw()=5,false另外還支持如下命令:- LIST will show the list of windows:LIST com.android.launcher/com.android.launcher.Launcher4359e4d0 TrackingView435b00a0 StatusBarExpanded StatusBar43484c58 KeyguardDONE.3: 架構(gòu)實(shí)現(xiàn)前兩節(jié)講了用Android SDK自帶的tool-hierarc

39、hyviewer來捕獲Activity上Element,并分析了其中的原理。對于要實(shí)現(xiàn)GUI自動(dòng)化,還有哪些工作沒有完成呢?n Invoke界面上的Element,如點(diǎn)擊按鈕,在文本框中輸入內(nèi)容等n Press手機(jī)自身所有的按鍵,如HOME鍵,Menu鍵,左右上下方向鍵,通話鍵,掛機(jī)鍵等n 判斷測試結(jié)果前面說過,直接從Emulator內(nèi)部獲取當(dāng)前Activity上的Element這條路已經(jīng)斷了,同理,探索像UI Automation上一樣Invoke Element的操作估計(jì)是行不通了,因?yàn)槟隳貌坏紼lement的對象實(shí)例,所以實(shí)例所支持的方法當(dāng)然也沒有辦法拿到。怎么辦?實(shí)在不行,基于坐標(biāo)來對

40、Element進(jìn)行觸發(fā)總可以吧。在Windows中發(fā)送基于坐標(biāo)發(fā)送鍵盤和鼠標(biāo)事件一般是在無法識別Element的情況下,想的最后一招,這使我想起起了Android中的monkey測試,對著屏幕就是一通亂點(diǎn),壓根就不管點(diǎn)的是什么。所幸的是,當(dāng)前Android系統(tǒng)中我們得到了Element的屬性信息,其中就包括坐標(biāo)信息,而且這種信息是具有彈性的,也就是說即使Element的坐標(biāo)隨著開發(fā)的改變而有所變化,也不用擔(dān)心,因?yàn)楫?dāng)前的坐標(biāo)是實(shí)時(shí)獲得的。那么怎樣才能給Element發(fā)送模擬按鍵等操作呢?總不能用Windows當(dāng)前的鍵盤和鼠標(biāo)事件吧,那樣一旦模擬器的位置改變或失去焦點(diǎn),啥都白搭,風(fēng)險(xiǎn)太大了。看來

41、給Emulator內(nèi)部發(fā)送模擬按鍵等操作比較靠譜。查了一下SDK,其中確實(shí)有這樣的方法存在,但是我們當(dāng)前的測試基礎(chǔ)架構(gòu)程序位于Emulator外部,怎么辦?突然想起了hierarchyviewer的實(shí)現(xiàn)機(jī)制,通過Socket來發(fā)送信息。Hierarchyviewer有系統(tǒng)自帶的進(jìn)程給予答復(fù)響應(yīng)(具體是哪個(gè)進(jìn)程進(jìn)行的響應(yīng)不清楚,沒有研究過)。那么我們也來模擬做一個(gè)Listener總可以吧。其實(shí)對于模擬按鍵發(fā)送,網(wǎng)上的帖子很多,但大部分是基于一種方式實(shí)現(xiàn)的,IWindowManager接口。不巧的是,SDK并沒有將該接口提供為public,所以需要用android源碼替代android.jar包進(jìn)

42、行編譯的方式進(jìn)行繞行,感覺方法有點(diǎn)復(fù)雜。在后面另一篇系列文章中我會(huì)列出我在網(wǎng)上看到的另一種基于Instrumentation和MessageQueue的機(jī)制實(shí)現(xiàn)方法。最后就剩下判斷測試結(jié)果了。判斷測試結(jié)果一般分為如下兩種:外部條件是否滿足,如文件是否產(chǎn)生,數(shù)據(jù)是否生成等;內(nèi)部條件是否滿足,如對應(yīng)的Element是否出現(xiàn)或消失,Element上內(nèi)容如字符串是否有變化。對于前一種本文不予討論,后一種情況下,Element出現(xiàn)或消失可以通過hierarchyviewer來獲取。仔細(xì)研究過hierarchyviewer會(huì)發(fā)現(xiàn),它并沒有提供Element界面上內(nèi)容(Text)的屬性。這可有點(diǎn)暈了,好像又

43、要回到實(shí)現(xiàn)捕獲Activity實(shí)例的老路上來了。考慮圖像識別?這好像不靠譜。突然想到,4939端口上發(fā)送DUMP命令后的返回結(jié)果中會(huì)不會(huì)有此類hierarchyviewer沒有顯示出來的信息呢,萬幸,還真有。在我上一篇博文(Hierarchyviewer 捕獲Element的實(shí)現(xiàn)原理)中查詢mText字段,會(huì)發(fā)現(xiàn)mText=1,5這樣的信息,其實(shí)就是代表了計(jì)算器Button5上顯示的內(nèi)容5,逗號前的1表示后跟一位信息。至此,問題似乎都解決掉了。畫個(gè)基礎(chǔ)架構(gòu)圖做個(gè)總結(jié):4:模擬鍵盤鼠標(biāo)事件(Socket+Instrumentation實(shí)現(xiàn))通過Socket + Instrumentation實(shí)現(xiàn)

44、模擬鍵盤鼠標(biāo)事件主要通過以下三個(gè)部分組成:l Socket編程:實(shí)現(xiàn)PC和Emulator通訊,并進(jìn)行循環(huán)監(jiān)聽l Service服務(wù):將Socket的監(jiān)聽程序放在Service中,從而達(dá)到后臺運(yùn)行的目的。這里要說明的是啟動(dòng)服務(wù)有兩種方式,bindService和startService,兩者的區(qū)別是,前者會(huì)使啟動(dòng)的Service隨著啟動(dòng)Service的Activity的消亡而消亡,而startService則不會(huì)這樣,除非顯式調(diào)用stopService,否則一直會(huì)在后臺運(yùn)行因?yàn)镾ervice需要通過一個(gè)Activity來進(jìn)行啟動(dòng),所以采用startService更適合當(dāng)前的情形l Instru

45、mentation發(fā)送鍵盤鼠標(biāo)事件:Instrumentation提供了豐富的以send開頭的函數(shù)接口來實(shí)現(xiàn)模擬鍵盤鼠標(biāo),如下所述:sendCharacterSync(int keyCode) /用于發(fā)送指定KeyCode的按鍵sendKeyDownUpSync(int key) /用于發(fā)送指定KeyCode的按鍵sendPointerSync(MotionEvent event) /用于模擬TouchsendStringSync(String text) /用于發(fā)送字符串注意:以上函數(shù)必須通過Message的形式拋到Message隊(duì)列中。如果直接進(jìn)行調(diào)用加會(huì)導(dǎo)致程序崩潰。對于Socket編程

46、和Service網(wǎng)上有很多成功的范例,此文不再累述,下面著重介紹一下發(fā)送鍵盤鼠標(biāo)模擬事件的代碼:1. 發(fā)送鍵盤KeyCode:步驟1. 聲明類handler變量private static Handler handler;步驟2. 循環(huán)處理Message/在Activity的onCreate方法中對下列函數(shù)進(jìn)行調(diào)用private void createMessageHandleThread() /need start a thread to raise looper, otherwise it will be blocked Thread t = new Thread() public void run() Log.i( TAG,Creating handler . ); Looper.prepare(); handler = new Handler() public void handleMessage(Message msg) /process incoming messages here ; Looper.loop(); Log.i(

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論