第一篇:安卓學習心得
Android學習心得
-----093380117
計算機應用(1)
張峰
1.關于Activity
1.在一個Activity中使用多個View
如果把Activity看作MVC中的Control?它負責管理UI和接受事件(包括用戶的輸入),雖然說一個Activity通常對應一個屏幕,但事實上,我們是可以只用一個Activity管理多個不同的View來實現簡單的邏輯。首先,我們增加一個新的資源描述layout/second.xml。
除了一個“Hello中國”以外,增加一個按鈕可以返回前一個界面。然后,在代碼中我們要為helloTwo增加兩個方法,setViewOneCommand和setViewTwoCommand,分別處理一下在不同界面時,從資源里加載組件并為組件綁定一個事件處理器最后,我們需要在onCreate的時候,也就是啟動后的main界面上設置一下按鈕事件處理器。2.還是回到正道上,多個Activity之間的跳轉
Android中提供一個叫Intent的類來實現屏幕之間的跳轉,按文檔的說法,似乎他們也建議采用這種方法,Intent的用法比較復雜,現在我先看看它最簡單的用法。
這里的跳轉功能用Intent來操作,它的最簡單用法就是用函數setClass()設置跳轉前后兩個Activity類的實例,然后調用Activity自己的startActivity(intent)即可。最后一句finish()表示將當前Activity關掉(如果不關掉會如何?你可以自己試一下看效果,事實上有時我們是不需要關掉當前Activity的)。
然后,我們同樣弄一個Activity類HelloThreeB,代碼與前面的差不多,只是將setClass的兩個參數反一下,這樣就可以簡單地實現在兩個Activity界面中來回切換的功能了。
2.關于 Intent的使用
Intent分為兩大類,顯性的(Explicit)和隱性的(Implicit)。一般來說,intent要定位事件的目的地,無外乎需要以下幾個信息: 1.種類(category),比如我們常見的 LAUNCHER_CATEGORY 就是表示這是一類應用程序。
2.類型(type),在前面的例子中沒用過,表示數據的類型,這是隱性Intent定位目標的重要依據。
3.組件(component),前面的例子中用的是setClass,不過也可以用setComponent來設置intent跳轉的前后兩個類實例。4.附加數據(extras),在ContentURI之外還可以附加一些信息,它是Bundle類型的對象。
其實,如果是在一個應用內部,這種隱性的intent實在有點別扭,個人覺得,這種松藕合的實現方法,只適用于那些較大的系統或者多個不同的應用之間的調用,可手機上又有什么“較大”的系統呢?無非是可以與不同來源的多個應用之間方便地互操作而已,那么會是什么樣的場景呢?比如,給QQ好友發送gmail郵件,用GoogleMap查找QQ好友所在的位置?看上去挺不錯的。
關于這個ContentProvider,其實還有話說,它主要是的那些看似數據庫操作的方法我們都沒真正去實現呢。不過今天就到這里了,等下回再去研究吧。
3.關于ListActivity
準備一個List對象并借助Adapter就可以構造出一個列表。重載onListItemClick方法可以響應選擇事件,利用第一個參數可以訪問到這個ListView實例以得到選中的條目信息。這里有一點要說明的,就是如果更簡單的話,其實連那個setContentView都可以不要了,Android也會自動幫我們構造出一個全屏的列表。但是本例中我們需要一個TextView來顯示選中的條目,所以我們需要一個layout.mainb描述一下這個列表窗口。
這里需要注意的是那個ListView的ID,是系統自定義的android:list,不是我們隨便取的,否則系統會說找不到它想要的listview了。然后,在這個listview之外,我們又增加了一個TextView,用來顯示選中的條目。
再來說說這里用到的ArrayAdapter,它的構造函數中第二個參數是一個資源ID,ArrayAdapter的API文檔中說是要求用一個包含TextView的layout文件,平臺用它來顯示每個選擇條目的樣式,這里的取值是R.layout.list_row,所以,我們還有一個list_row.xml文件來描述這個布局,相當簡單。
從ArrayAdapter上溯到BaseAdapter,發現還有幾個同源的Adapter也應該可以使用,象SimpleAdapter和CursorAdapter,還是做個例子來實驗一下吧。
然后,在HelloTwoB中的onCreate函數中,修改代碼,有幾個不同:items的元素是HashMap實例,這是一點變化,然后構造函數除了要求items以外,還要求提供一個string[]來說明用hash表中的哪個字段顯示在列表中,而后是一個資源ID的數組。
因為單純的CursorAdapter是抽象類,所以我用的是它的子類SimpleCursorAdapter,很好理解,先用ContentResolver查詢通訊簿得到一個游標,然后告訴SimpleCursorAdapter要用其中的People.NAME作為顯示項來構造出一個adapter即可。4.關于Dialog
注意到android.app包下除了Dialog(可用于制作復雜的對話框)以外,還包括了幾個系統定義好的對話框類,如DatePickerDialog、TimePickerDialog及AlertDialog。
其中AlertDialog我上回用過一次,基本上就那樣子了,今天看看另外兩個對話框的使用吧。
很簡單的,無非是需要一個OnDateSetListener接口的實現而已,在它里面的dateSet方法中就可以得到選擇的日期了。而TimePickerDialog與DatePickerDialog使用如出一轍。
看看另一個ProgressDialog的用法吧,這個類與AlertDialog一樣包含了多個static的方法,所以使用起來是非常方便的。比如說,如果我們需要用它來表示一個長時間的操作。
5.關于Service和Notification
大略地看了一下android.app下的Service類,覺得它與Activity非常相似,只是要注意幾個地方:
1.生命周期,Service的從onCreate()->onStart(int,Bundle)->onDestroy()顯得更為簡單。但是它的onStart是帶參數的,第一個ID可用來標識這個service,第二個參數顯示是用來傳遞數據的了。比較Activity,傳遞數據的Bundle是在onCreate就帶進入的。
2.Service的啟動由Context.startService開始,其實Activity或者Service都是Context的派生類。結束于Context.stopService()或者它自己的stopSelf()。
3.Service還有一個與Activity不一樣的是它可以由另一個Context去綁定一個已存在的Service。就是這個方法Context.bindService(),被綁定的Service要求是已經onCreate了但可以沒有onStart。在Service類中有個抽象方法getBinder()可以得到這個IBinder對象。關于這方面的細節,以后再看,這里只做個記錄罷。
4.與Service有關的還有一個安全的問題,可以在AndroidManifest.xml中用
6.GridView與ImageView
簡單一點吧,就瞧瞧那個Grid的效果,Android提供了一個GridView,不過從APIDemo中看來,它似乎與PC上的GRID差別還是挺大的,更像那個IconView的感覺。不知道Android中如何實現表格界面?雖然在移動終端上,表格一般不會有誰使用,大家似乎更傾向于使用ListView,而Android對于ListView則有更簡單的實現ListActivity。
很簡單,只要重載幾個方法就可以了,關鍵是那個getView方法,它負責構建出每個單元格中的對象實例。這里我們構造的是一個ImageView實例。
然后就是同樣的將這個Adapter賦給GridView即可,大家可以看看效果,注意在做這個例子前,先放幾個小圖片到res/drawable目錄下,buildproject一下就可以得到那個R.drawable.a了(這里的a是圖像文件名,如a.png)。
在getView方法中我們使用了ImageView類,這又是一個widget。除了上面用到的幾個方法以外,還有以下幾個方法值得注意: 與圖像來源有關的方法,我們只用了資源文件的方式。
還是習慣性跑題了,其實,我是想通過我對這個類的無數次Debugger跟進,說說它的多線程異步處理的解決策略的。他的基本策略如下: 1.當你實例化一個AsyncQueryHandler類時(包括其子類...),它會單件構造一個線程(后面會詳述...),這個線程里面會構建一個消息循環。
2.獲得該消息循環的指針,用它做參數實例化另一個Handler類,該類為內部類。至此,就有了兩個線程,各自有一個Handler來處理消息。3.當調用onXXX的時候,在XXX函數內部會將請求封裝成一個內部的參數類,將其作為消息的參數,將此消息發送至另一個線程。4.在該線程的Handler中,接受該消息,并分析傳入的參數,用初始化時傳入的ContentResolver進行XXX操作,并返回Cursor或其他返回值。
5.構造一個消息,將上述返回值以及其他相關內容綁定在該消息上,發送回主線程。
6.主線程默認的AsyncQueryHandler類的handleMessage方法(可自定義,但由于都是內部類,基本沒有意義...)會分析該消息,并轉發給對應的onXXXComplete方法。
7.用戶重寫的onXXXComplete方法開始工作。
這就是它偷偷摸摸做過的事情,基本還是很好理解的。我唯一好奇的是它的線程管理方式,我猜測他是用的單件模式。第一個AsyncQueryHandler的實例化會導致創建一個線程,從此該線程成為不死老處男,所有的ContentResolver相關的工作,都由該線程統一完成。個人覺得這種解決方式很贊。本來這個線程的生命周期就很難估量,并且,當你有一個ContentProvider的請求的時候,判斷你會做更多的類似操作并不過分。就算錯了,花費的也只是一個不死的線程(與進程同生死共存亡...),換來的卻是簡單的生命周期管理和無數次線程生死開銷的節約。同時另外一個很重要的問題,他并會涉及到單件中數據同步的問題,每個類都有各自的Handler類,彼此互不干擾,分發可以分別進行。當多個數據請求的時候,在同一個ContentResolver上進行的可能微乎其微,這就避免了堵塞。總而言之,這套解決辦法和Android的整體設計算是天作之合了。
所以建議,如果你有什么非ContentProvider操作,卻需要異步多線程執行的話,模擬一套,是個不錯的策略,當然,具體情況具體分析,生搬硬套是學不好馬列主義的。
7.顯示控件使用
Android的界面顯示同樣也是基于控件的。通常是用View(包括ViewGroup)控件配上XML的樣式來做的。具體細節不想說了,可以參考 Samples里的ApiDemos/View,和View的Doc,以及Implementing a UI這篇Doc。其他還有很多,感覺算是SDK講述的最多的內容。
從控件的使用上,和網頁的設計類似,盡量用parent_width之類的抽象長度,用Theme來做風格,抽取所有的字串等信息做本地化設計。相關內容參看Implementing a UI就好。
一類比較重要的是數據綁定控件。如果做過ASP.Net會從中看到很多類似的地方。一個支持數據綁定的控件,比如ListView。可以通過一個 ListAdapter綁定到一個數據源上。ListAdapter是一個抽象類,主要的實現類包括SimpleAdapter和 SimpleCursorAdapter。前者是綁定一個靜態的Array,后者是綁定一個動態的Cursor。Cursor前面說過,是一個指向數據源的隨機迭代器,將View綁定到Cursor通常要設置這樣幾個參數。一個是每一行的樣式,稱作Row Layout,其實就是一個普通的Layout的XML文件。還有就是一個列和現實控件的對應關系。那個控件顯示哪個列的值,這是需要配置的。為了定制一個良好的數據顯示控件,最簡單你可以定制很PP的Row Layout,復雜一點就是可以重載綁定控件View,或者是適配器ListAdapter。如果是一個數據顯示密集的應用,且你對UI有些追求,這個工作估計是必不可少的。
一個主要用于顯示數據內容的Activity,可以選擇派生自ListActivity。它提供了一個具有ListView 的Layout,還有simple_list_item_1, simple_list_item_2, two_line_list_item等默認的Row Layout,還有一些比較不錯的API,和可供響應選擇Item的事件。可以滿足你比較基礎的需求。如果你覺得只有一個ListView的界面太突兀,你可以為這個ListActivity指定一個Layout,需要注意的是,你需要提供一個id為@android:id/list的ListView控件,避免Activity在內部偷偷尋找該控件的時候失敗。
除了這些要求,做好UI還有注意易用性和效率。快捷鍵是一個比較不錯的選擇,在 Activity中調用setDefaultkeyMode(SHORTCUT_DEFAULT_KEYS),可以開啟快捷鍵模式,然后你可以將菜單綁定到指定快捷鍵上就OK了。個人覺得Tip也是一個比較重要的東西,但目前觀察看來,這個東西只能夠自己提供了。界面的動態性有時候是不可避免的,比如說菜單就是一個需要經常根據光標位置提供不同的選項。這個東西Android很人道的考慮到了,你可以參看NodeList這個Sample。它采取的應該是一個靜態模擬動態的方式,這樣有助于提高速度。你也可以利用ViewInflate,動態從一個XML創建一個控件。成本據Doc說很大,不到萬不得已不要使用。
8.Intent消息傳遞
在前面寫Android的ContentProvider時候,可以看到那是基于觀察者模式的一個消息傳遞方法。每一個Cursor、ContentResolver做為一個小的注冊中心,相關觀察者可以在這個中心注冊,更新消息由注冊中心分發給各個觀察者。而在MFC或Winform中,都會形成一個消息網,讓消息在網中流動,被各節點使用、吃掉或者在出口死掉。
相比之下,我個人覺得基于Intent的Android核心消息傳遞機制是有所不同的。它應該會有一個全局性的注冊中心,這個注冊中心是隱性的,整個Android系統中就那么一個。所有的消息接收者,都被隱形的注冊到這個中心。包括Activity,Service和IntentReceiver。其實說隱形注冊是不確切的,所有注冊都還是我們手動告訴注冊中心的,只是與傳統的方式不一樣,我們通常不是通過代碼,而是通過配置文件來做。在應用的Manifest中,我們會為一些Activity或Service添加上Intent-filter,或在配置文件中添加
當程序有一個消息希望發出去的時候,它需要將消息封裝成一個Intent,并發送。這時候,應該是有一個統一的中心(恩,有可能Android底層實現的時候不是,但簡單這樣看是沒問題的...)接受到這個消息,并對它進行解析、判定消息類型(這個步驟降低了耦合...),然后檢查注冊了相匹配的filter或receiver,并創建或喚醒接收者,將消息分發給它。這樣做有很多好處。雖然這種傳遞有的時候不如點對點的傳遞快(這有些需要速度的地方,我們看到Android會通過直接通信來做),但有時候又因為它只經過一跳(姑且這么叫吧...),比復雜的流動又要更快。更重要的是,它耦合性低,在手機平臺這種程序組件多變的條件下使用十分適合。并且它可以很容易實現消息的精確或模糊匹配,彈性很大。(我個人曾想在開發一個C++二次平臺的時候引入這樣的機制,但在C++中,建立一套完整的數據marshal機制不容易,相比之下,用java來做會簡單很多...)
恩,廢話說了很多,具體講講Android中Intent的使用。當你有一個消息需要傳遞,如果你明確知道你需要哪個Activity或者其他Class來響應的話,你可以指定這個類來接受該消息,這被稱為顯性發送。你需要將Intent的class屬性設置成目標。這種情況很常見,比如startActivity的時候,會清楚當前Activity完了應該是哪個Activity,那就明確的發送這個消息。
但是,有的時候你并不確定你的消息是需要具體哪個類來執行,而只是知道接收者該符合哪些條件。比如你只需要有一個接收者能顯示用戶所選的數據,而不想制定某個具體的方法,這時候你就需要用到隱形發送(傳統上,我們可能會考慮用多態,但顯然這種方式更為靈活...)。在Android中,你可以為Intent指定一個action,表示你這個指令需要處理的事情。系統為我們定義了很多Action類型,這些類型使系統與我們通信的語言(比如在Activity里面加一個Main的filter,該activity就會做成該應用的入口點),當然你也可以用于你自己的應用之間的通信(同樣當然,也可以自定義...)。強烈建議,在自己程序接收或發出一個系統action的時候,要名副其實。比如你響應一個view動作,做的確實edit的勾當,你發送一個pick消息,其實你想讓別人做edit的事,這樣都會造成混亂。當然只有Action有時候是不夠的,在Android中我們還可以指定catalog信息和type/data信息,比如所有的顯示數據的Activity,可能都會響應View action。但很多與我們需要顯示的數據類型不一樣,可以加一個type信息,明確的指出我們需要顯示的數據類型,甚至還可以加上一個catalog信息,指明只有你只有按的是“中鍵”并發出這樣的消息才響應。從上面可以看出,Android的Intent可以添加上class, action, data/type, catalog等消息,注冊中心會根據這些信息幫你找到符合的接收者。其中class是點對點的指示,一旦指明,其他信息都被忽略。Intent中還可以添加key/value的數據,發送方和接收方需要保持統一的key信息和value類型信息,這種數據的marshal在java里做,是不費什么力氣的。
Android的Intent發送,可以分成單播和廣播兩種。廣播的接收者是所有注冊了的符合條件的IntentReceiver。在單播的情況下,即使有很多符合條件的接收者,也只要有一個出來處理這個消息就好(恩,個人看法,沒找到確切條款或抉擇的算法,本來想實驗一下,沒來得及...),這樣的情況很容易理解,當你需要修改某個數據的時候,你肯定不會希望有十個編輯器輪流讓你來處理。當廣播不是這樣,一個receiver沒有辦法阻止其他receiver進行對廣播事件的處理。這種情況也很容易理解,比如時鐘改變了,鬧鐘、備忘錄等很多程序都需要分別進行處理。在自己的程序的使用中,應該分清楚區別,合理的使用。
9.ContentProvider數據模型
數據庫操作
從我目前掌握的知識來看,SQLite比較輕量(沒有存儲過程之類的繁雜手段),用起來也比較簡單。實例化一個SQLiteDatabase類對象,通過它的APIs可以搞定大部分的操作。從sample中看,Android中對db的使用有一種比較簡單的模式,即派生一個 ContentProviderDatabaseHelper類來進行SQLiteDatabase對象實例的獲取工作。基本上,ContentProviderDatabaseHelper類扮演了一個singleton的角色,提供單一的實例化入口點,并屏蔽了數據庫創建、打開升級等細節。在ContentProvider中只需要調用ContentProviderDatabaseHelper的openDatabase方法獲取SQLiteDatabase的實例就好,而不需要進行數據庫狀態的判斷。URI 像進行數據庫操作需要用SQL一樣,對ContentProivder進行增刪改查等操作都是通過一種特定模式的URI來進行的(ig:content: //provider/item/id),URI的能力與URL類似,具體細節可以查看SDK。建立自己的ContentProvider,只需要派生 ContentProivder類并實現insert, delete, update等抽象函數即可。在這些接口中比較特殊的是getType(uri)。根據傳入的uri,該方法按照MIME格式返回一個字符串(==!沒聽過的詭異格式...)唯一標識該uri的類型。所謂uri的類型,就是描述這個uri所進行的操作的種類,比如content://xx/a與 content://xx/a/1不是一個類型(前者是多值操作,后者是單值),但content://xx/a/1和content://xx/a/2 就會是一個類型(只是id號不同而已)。
在ContentProvider通常都會實例化一個ContentURIPraser來輔助解析和操作傳入的URI。你需要事先(在static域內)為該ContentURIPraser建立一個uri的語法樹,之后就可以簡單調用 ContentURIPraser類的相關方法進行uri類型判斷(match方法),獲取加載在uri中的參數等操作。但我看來,這只是在使用上簡化了相關操作(不然就需要自己做人肉解析了...),但并沒有改變類型判定的模式。你依然需要用switch...case...對uri的類型進行判斷,并進行相關后續的操作。從模式來看,這樣無疑是具有強烈的壞味道,類似的switch...case...代碼要出現N此,每次一個 ContentProvider做uri類型的增減都會需要遍歷修改每一個switch...case...,當然,如果你使用模式(策略模式...)進行改造對手機程序來說無疑是崩潰似的(類型膨脹,效率降低...),所以,只能是忍一忍了(恩,還好不會擴散到別的類中,維護性上不會有殺人性的麻煩...)。增刪改查
ContentProvider 和所有數據源一樣,向外提供增刪改查操作接口,這些都是基于uri的指令。進行insert操作的時候,你需要傳入一個uri和 ContentValues。uri的作用基本就限于指明增減條目的類型(從數據庫層面來看就是table名),ContentValues是一個 key/value表的封裝,提供方便的API進行插入數據類型和數據值的設置和獲取。在數據庫層面上來看,這應該是column name與value的對應。但為了屏蔽ContentProvider用戶涉及到具體數據庫的細節,在Android的示例中,用了一個小小的模式。它為每一個表建一個基于BaseColumn類的派生類(其實完全可以不派生自BaseColumn,特別當你的表不基于默認的自動id做主鍵的時候),這個類通常包括一個描述該表的ContentURI對象和形如 public static final TITLE = “title”這樣的column到類數據的對應。從改變上角度來看,你可以修改column的名字而不需要更改用戶上層代碼,增加了靈活性。insert方法如果成功會返回一個uri,該uri會在原有的uri基礎上增加有一個row id。對于為什么使用row id而不是key id我想破了腦袋。到最后,我發現我傻了,因為ContentProvider不一定需要使用數據庫,使用數據庫對應的表也可以沒有主鍵,只有row id,才能在任何底層介質下做索引標識。
但,基于row id在刪除和修改操作是會造成一定的混亂。刪除和修改操作類似。刪除操作需要傳入一個uri,一個where字串,一組where的參數(做條件判定...),而修改操作會多一個ContentValues做更新值。著兩個操作的uri都支持在末尾添加一個row id。于是混亂就出現了。當在where參數中指明了key id,而在uri中提供了row id,并且row id和key id所指函數不一致的時候,你聽誰的?示例代碼中的做法是完全無視row id(無語...),如此野蠻的方式我估計也只能在示例中出現,在實際中該如何用,恩,我也不知道。幸運的是,我看了下上層對 ContentProvider的刪除操作,其實都不會直接進行,而是通過調用Cursor的delete方法進行,在這前提下,我想Cursor會處理好這些東西吧。
最后一個操作是查詢操作,可以想見,查詢的參數是最多的,包括uri和一組條件參數。條件參數類型和標準的sql類似,包括 sort, projection 之類的。從這些參數到sql語句的生成,可以尋求QueryBuilder類的幫助,它提供了一組操作接口,簡化了參數到sql的生成工作,哪怕你不懂 sql都完全沒有問題(這話說的我自己都覺得有點懸...)。查詢返回一個Cursor。Cursor是一個支持隨機讀寫的指針,不僅如此,它還提供了方便的刪除和修改的API,是上層對ContentProvider進行操作一個重要對象,需要仔細掌握(Cursor還可以綁定到view上,直接送顯,并與用戶進行交互,真是程序越往上,封裝越好,工作越機械沒有復雜性了...)。數據模型
在與界面打交道的Cursor、ContentResolver等數據操作層中,大量采用觀察者模式建立數據層與顯示層的聯系。一個顯示層的視圖,可以做成某一種觀察者注冊到Cursor或ContentResolver等數據中間層中,在實現底層ContentProvider中,我們需要特別注意在對數據進行修改操作(包括增刪改...)后,調用相應類型的notify函數,幫助表層對象進行刷新(還有一種刷新方式是從一個view發起的)。可以看到 Android的整體數據顯示框架有點像MVC的方式。Cursor、ContentResolver相當于控制層,數據層和顯示層的交互通過控制層來掌管,而且控制層很穩定不需要特別定制,通常工作只在定制數據層和顯示層空間,還是比較方便和清晰的。
10.學習感想
通過這學期對安卓的學習,大概了解了以上一些知識,對安卓有了初步的了解,這幾個月給我的東西我想用有形的和無形的兩部分概敘,形的當然就是技術水平的長進,雖然其中肯定有很多的不足,相信慢慢會體會到。
第二篇:安卓 課程學習心得
心得體會
學號: 姓名: 班級:
一開始接觸 Android 是從自己的手機開始的,覺得它很酷,是我喜歡的風格,然后我就通過了一些網絡渠道去了解Android。在選課的時候發現有這個課程,于是我就報名了。剛開始接觸 Android開發時感覺到它很有意思,在界面開發上和 web 也可以形成了相通的架構,更加方便,視覺上也是非常的酷。Android作為新興的手機操作系統,適應潮流的發展,在一定程度上迎合了現代人們最求效率和最求完美的心態,再加上的它的先進之處,所以 Android 的發展很快,Android 的應用資源也越來越廣泛,現在的 Android 正在快速形成一個只能手機王國,給人們提供日常娛樂和辦公的平臺,無論在哪些方面,Android 的表現總是能夠讓人滿意,它正在快速地占領手機終端,未來的智能手機領域將是 Android 的天下,越來越多的人選用 Android平臺的手機。如果說追求蘋果是因為蘋果的高端與美感,那么追求 Android 則是因為它的先進性開源性,也正是因為 Android 這些吸引人們矚目的特點,才會有越來越多的人對 Android 充滿激情,Android 的發展也才能這樣的迅猛,所以在這里要先謝謝 Goolge,以及那些充滿激情的開發者們。首先在界面上,我們同樣可以通過不同布局進行設計非常酷的界面,這些界面可以通過 include 進行引入,我們可以通過一些公用的方法寫個 BaseActivity 這個基類,通過繼承方式比較不錯的實現了 Activity 的界面,因為這樣你可以 Header(頭部)和 Footer(尾部)進行處理一些觸發事件或者特效等。布局模式以相對模式為主,線線布局模式可以在比較簡單的 include 進行完成,最重要的一點就是:我們可以自己通過重寫方法或者通過實現 View 或者 Layout 等類進行擴充項目需要的布局(或者控件),在學習界面中,Android 為我們提供了很好的類似反射機制,通過 Layout 文件夾下的配置文件,可以快速的形成界面,在配置文件可以設置屬性或者樣式都是很快捷方便。對比較特殊的界面也可以通過處理嵌入到指定的界面,同樣可以通過java 代碼直接創建View 進行添加,不過這種方式比較復雜。對一些點擊、選中、按鍵等處理的事件,界面之間的 跳轉 Intent 管理,通過 Bundle 對數據在界面之間進行傳輸。其次在手機交互式通信服務中,學習了 Android 手機之間進行短信發送、廣播、對廣播的監聽、服務等。
這次的課程我們主要學習了航班系統的設計,首先我們要建立航班查詢:旅客就可通過網絡訪問該系統客戶端網址,可根據旅客提供的出發時間、出發地點和目的地、艙位要求等,查詢滿足旅客要求的航班。通過檢索可得到航班的相關信息,從而可以方便旅客訂票并掌握所需信息,同時可減少工作人員的工作量。
第二,我們要建立旅客訂票:旅客將訂票的相關信息通過工作人員輸入系統客戶端。客戶端將旅客的訂票信息通過網絡傳送給服務端,服務端根據接收到的信息由航班安排系統為旅客安排座位并返回相應的確認信息給該客戶端。訂票信息生成后,存入相應的存儲區域,并對數據庫進行數據提交。客戶端打印取票單及帳單給旅客,旅客在登機前,經信息核審后,即可領取機票登機。
第三,航班信息管理:航空公司可將所有航班的信息存入數據庫,方便用戶對航班基本信息查詢,相 關工作人員可根據公司要求,經系統身份認證后登錄并對航班信息進行修改等操作,從而使 航班信息便于管理。
第四:航班安排:從客戶端接收到旅客的訂票信息,該系統可在短時間內處理旅客航班問題。將 訂票信息送往數據庫并更新,客戶端的航班查詢信息也同步更新。節省時間的同時,也能讓 旅客得到最新的航班信息。
第五,售票管理:旅客不僅可在各客戶端進行機票預定,也可直接在機場的售票處購票,購票信息由系統提交到數據庫進行管理更新。
第六,退票管理:機票有效期內,旅客若需退票,可在退票處進行退票。退票信息,由工作人員輸入系統,系統對訂票信息或售票信息進行刪除更新。
第七,票銷售情況核算:因為航空公司機票銷售量大,而航空公司為了公司的經營,有需要在一定的時 間階段了解公司機票的銷售情況。而龐大的數據量通過人工來完成,似乎不太現實,而該系 統可幫助航空公司進行售票情況的核算。
這個課程緊跟住了現代科技的發展,讓我們在第一時間和先進的科學技術做了一個親密的接觸,這樣的課程能夠點燃我們對某一個新興領域的激情,這算是一個啟蒙,讓我們對 Android 先有了一個大概的了解,這個課程不一定能讓我們很好的掌握 Android 的理念或者開發,但是能夠讓我們對 Android 產生濃厚的興趣,讓我們燃起探索Android 的欲望,我想這樣就已經足夠了。
第三篇:如何學習安卓
如何學習安卓
想學編程開發,那要先會一門編程語言,現在可以試著去學學C語言,雖然這個安卓沾不上邊,但是,C語言的編程思想還是很重要的,學完了C語言之后,他的語法基本上和所有的編程語言都很相像,能影響你的思維,幫助你理解其他的編程語言的。之后呢,在好好看看《數據結構》,這很重要。然后再去學學Java語言,因為Android的應用的開發語言用的是Java,所以一定要好好學習。
最后了解下數據庫,我們在學習數據庫之前都先學了《數據庫原理》《離散數學》《關系代數》,有了這些基礎之后再去學數據庫,數據庫也有很多可以選擇的,推薦mysql。
加油!
第四篇:安卓實驗報告
安卓實驗報告
班級:學號:姓名:
xxxxx
11111111
xxxx
實驗一:Activity生命周期的測試
一:實驗目的
掌握使用Eclipse開發Android應用開發程序的方法; 掌握Android虛擬設備的創建方法; 了解Android的程序結構;
了解使用命令行創建Android程序方法;
了解Activity生命周期,理解Activity事件回調,onRestoreInstanceState()和 onSaveInstanceState兩個函數的使用。
二:實驗設備
Eclipse 開發Android 應用 Android虛擬設備(AVD)
三:實驗內容
(1)正常啟動ActivityLife,然后單擊用戶界面的“結束程序”按鈕關閉程序。
(2)正常啟動ACtivityLife,然后通過“撥號鍵”啟動內置的撥號程序,再通過“回 退建” 退出撥號程序,使ActivityLife重新顯示在屏幕中。
四:實驗核心代碼
package com.example.activitylife;
import android.app.Activity;import android.app.ActionBar;import android.app.Fragment;import android.os.Bundle;import android.util.Log;import android.view.LayoutInflater;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.widget.Button;import android.os.Build;
public class MainActivity extends Activity { private static String TAG=“LIFECYCLE”;@Override
protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState);setContentView(R.layout.fragment_main);Log.i(TAG,“(1)onCreate()”);Button button =(Button)findViewById(R.id.btn_finish);button.setOnClickListener(new OnClickListener(){
public void onClick(View view){
// TODO Auto-generated method stub
finish();
} });}
@Override
protected void onStart(){ // TODO Auto-generated method stub
super.onStart();Log.i(TAG,“(2)onStart()”);} @Override
protected void onRestoreInstanceState(Bundle savedInstanceState){ // TODO Auto-generated method stub
super.onRestoreInstanceState(savedInstanceState);Log.i(TAG,“(3)onRestoreInstanceState()”);} @Override
protected void onResume(){ // TODO Auto-generated method stub
super.onResume();Log.i(TAG,“(4)onResume()”);} @Override
protected void onSaveInstanceState(Bundle outState){ // TODO Auto-generated method stub
super.onSaveInstanceState(outState);Log.i(TAG,“(5)onSaveInstanceState()”);} @Override
protected void onRestart(){ // TODO Auto-generated method stub
super.onRestart();Log.i(TAG,“(6)onRestart()”);} @Override
protected void onPause(){ // TODO Auto-generated method stub
super.onPause();Log.i(TAG,“(7)onPause()”);} @Override
protected void onStop(){ // TODO Auto-generated method stub
super.onStop();Log.i(TAG,“(8)onStop()”);} @Override
protected void onDestroy(){ // TODO Auto-generated method stub
super.onDestroy();Log.i(TAG,“(9)onDestroy()”);} } 五:運行結果截圖:
實驗二:用戶界面——自我介紹
一:實驗目的:
了解各種界面控件的使用方法;
掌握按鍵事件和觸摸事件的處理方法;
掌握radioButton和radioGroup的使用方法。
二:實驗設備
Eclipse 開發Android 應用 Android虛擬設備(AVD)
三:實驗內容
要求寫一個自我介紹的安卓應用,包括姓名,性別,愛好,其中性別用radioButton選項編寫,點擊提交時,姓名,性別,愛好會在下面顯示出來。
四:實驗核心代碼:
public class MainActivity extends Activity { private EditText editText1;private EditText editText2;private EditText editText3;private TextView textView1;private TextView textView2;private TextView textView3;private RadioGroup radioGroup;private RadioButton radioButton1;private RadioButton radioButton2;private Button button;protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText1 =(EditText)findViewById(R.id.e1);
editText2 =(EditText)findViewById(R.id.e2);
textView1 =(TextView)findViewById(R.id.t1);
textView2 =(TextView)findViewById(R.id.t2);
textView3 =(TextView)findViewById(R.id.t3);
radioGroup =(RadioGroup)findViewById(R.id.RadioGroup1);
radioButton1 =(RadioButton)findViewById(R.id.RadioButton1);
radioButton2 =(RadioButton)findViewById(R.id.RadioButton2);
button =(Button)findViewById(R.id.button1);
radioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener(){
public void onCheckedChanged(RadioGroup arg0, final int arg1){
button.setOnClickListener(new View.OnClickListener(){
public void onClick(View arg0){
String str = editText1.getText().toString().trim();
String str1 = editText2.getText().toString().trim();
textView1.setText(“姓名:”+str);
textView3.setText(“愛好:”+str1);
if(arg1 == R.id.RadioButton1)
textView2.setText(“性別:”+“男”);
else if(arg1 == R.id.RadioButton2)
textView2.setText(“性別:”+“女”);
}
});
}
});} } 五:運行結果截圖:
實驗三:不同界面的切換
一:實驗目的
掌握各種界面布局的特點和使用方法;
掌握選項菜單,子菜單和快捷菜單的使用方法。
二;實驗設備
Eclipse 開發Android 應用 Android虛擬設備(AVD)
三;實驗內容:
設計一個Tab標簽頁,實現LinearLayout,RelativeLayout,AbsoluteLayout三種分頁面之間的切換,每個頁面的內容包括用戶名和確定,取消兩個按鈕
四:實驗核心代碼: AndroidMainfest.xml:
public class MainActivity extends TabActivity { protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);TabHost tabHost=getTabHost();LayoutInflater.from(this).inflate(R.layout.tab1,tabHost.getTabContentView(),true);LayoutInflater.from(this).inflate(R.layout.tab2,tabHost.getTabContentView(),true);LayoutInflater.from(this).inflate(R.layout.tab3,tabHost.getTabContentView(),true);tabHost.addTab(tabHost.newTabSpec(“TAB1”).setIndicator(“線性布局”).setContent(R.id.layout01));tabHost.addTab(tabHost.newTabSpec(“TAB1”).setIndicator(“絕對布局”).setContent(R.id.layout02));tabHost.addTab(tabHost.newTabSpec(“TAB1”).setIndicator(“相對布局”).setContent(R.id.layout03));} } Tab1,java public class Tab1 extends Activity { public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.tab1);} }
Tab2.java public class Tab2 extends Activity{ public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState);setContentView(R.layout.tab2);} }
Tab3.java public class Tab3 extends Activity{ public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState);setContentView(R.layout.tab3);} }
五:運行結果截圖:
實驗四:登陸界面和廣播消息
一:實驗目的
了解使用Intent進行組件通信的原理; 了解Intent過濾器的原理與匹配機制;
掌握發送和接受廣播消息的方法。
二:實驗設備
Eclipse 開發Android 應用 Android虛擬設備(AVD)
三:實驗內容
先寫一個登陸界面,包括用戶名,密碼,點擊登陸時實現頁面的跳轉功能,在第二個頁面使用Intent發送消息,并調用sendBroadcast()函數把Intent攜帶的消息傳送出去,用BroadcastReceiver接受廣播消息,在頁面下方顯示廣播內容。
四;實驗核心代碼:
public class MainActivity extends Activity { private Button button;@Override
protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);button=(Button)findViewById(R.id.button1);button.setOnClickListener(new View.OnClickListener(){
public void onClick(View arg0){
Intent intent=new Intent(MainActivity.this,Second.class);
startActivity(intent);
} });} } public class Second extends Activity { private Button button2;private EditText editText;protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
Intent intent=getIntent();
editText=(EditText)findViewById(R.id.e1);
button2=(Button)findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener(){
public void onClick(View arg0){
Intent intent=new
Intent(“com.example.broadcasttest.MY_BROADCAST”);
intent.putExtra(“message”, editText.getText().toString());
sendBroadcast(intent);
}
});
}
public class MyBroadcastReceiver extends BroadcastReceiver{ public void onReceive(Context context, Intent intent){
String msg=intent.getStringExtra(“message”);
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();} } android:name=“.Second”>
五:運行結果截圖
實驗五:Service綁定實現數據運算
一:實驗目的
了解Service的原理和用途;
掌握本地服務的管理和方法; 掌握服務的隱式啟動和顯示啟動方法;
掌握遠程服務的綁定和調用方法。
二:實驗設備
Eclipse 開發Android 應用 Android虛擬設備(AVD)
三:實驗內容
以綁定方式使用Service,獲取Service實例,當點擊綁定服務時可以實現兩個數的求差和比較大小功能,并輸出結果,當點擊取消綁定服務時,則無法運算。
四:實驗核心代碼
public class MathService extends Service{ private final IBinder mBinder=new LocalBinder();public class LocalBinder extends Binder{ MathService getService(){
return MathService.this;} } public IBinder onBind(Intent intent){ Toast.makeText(this, “本地綁定:MathService”,Toast.LENGTH_SHORT).show();return mBinder;}
public boolean onUnbind(Intent intent){ Toast.makeText(this, “取消本地綁定:MathService”, Toast.LENGTH_SHORT).show();return false;}
public long sub(long a,long b){ return a-b;}
public int compare(long a,long b){ if(a>b)return 1;else if(a==b)return 0;else return-1;
} }
public class MainActivity extends Activity { private MathService mathService;private Button button1;private Button button2;private Button button3;private Button button4;private EditText editText1;private EditText editText2;private EditText editText3;private boolean isBound=false;@Override
protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);editText1=(EditText)findViewById(R.id.e1);editText2=(EditText)findViewById(R.id.e2);editText3=(EditText)findViewById(R.id.e3);button1=(Button)findViewById(R.id.but1);button2=(Button)findViewById(R.id.but2);button3=(Button)findViewById(R.id.but3);button4=(Button)findViewById(R.id.but4);button1.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
if(!isBound){
final Intent serviceIntent=new Intent(MainActivity.this,MathService.class);
bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE);
isBound=true;
}
}
});button4.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){ if(isBound){
isBound=false;unbindService(mConnection);
mathService=null;}
} });
button2.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
if(mathService==null){
editText3.setText(“未綁定服務”);
return;
}
String a = editText1.getText().toString();
long a1 = Long.parseLong(a);
String b = editText2.getText().toString();
long b1 = Long.parseLong(b);
long result=mathService.sub(a1, b1);
String msg=String.valueOf(a1)+“-”+String.valueOf(b)+
“=”+String.valueOf(result);
editText3.setText(msg);
} });
button3.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
if(mathService==null){
editText3.setText(“未綁定服務”);
return;
}
String a = editText1.getText().toString();
long a1 = Long.parseLong(a);
String b = editText2.getText().toString();
long b1 = Long.parseLong(b);
long result=mathService.compare(a1, b1);
if(result==1){
editText3.setText(a+“>”+b);
}
else if(result==0){
editText3.setText(a+“=”+b);
}
else {
editText3.setText(a+“<”+b);
}
} });} private ServiceConnection mConnection=new ServiceConnection(){
public void onServiceDisconnected(ComponentName arg0){
mathService=null;
}
public void onServiceConnected(ComponentName name, IBinder service){
mathService=((MathService.LocalBinder)service).getService();
} };}
實驗六:SQLite實現用戶的增刪改查
一:實驗目的
了解SQLite數據庫的特點和體系及結構;
掌握SQLite數據庫的建立和操作方法;
理解ContentProvide的用途和原理;
掌握ContentProvider的創建和使用方法。
二:實驗設備
Eclipse 開發Android 應用 Android虛擬設備(AVD)
三:實驗內容
使用SQlite數據庫實現用戶(包括:姓名,年齡,身高)的添加數據,全部顯示,清除顯示,全部刪除,ID刪除,ID查詢,ID更新的功能。
四:實驗核心代碼
public class MainActivity extends ActionBarActivity { private EditText et_name;private EditText et_sex;private EditText et_department;private EditText et_id;private EditText et_salary;private MyOpenHelper oh;private SQLiteDatabase db;private TextView tv;private LinearLayout ll;@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
oh = new MyOpenHelper(MainActivity.this, “test.db”, null, 1);
db = oh.getWritableDatabase();
et_name =(EditText)findViewById(R.id.et_name);
et_sex =(EditText)findViewById(R.id.et_sex);
et_department =(EditText)findViewById(R.id.et_department);
et_salary =(EditText)findViewById(R.id.et_salary);
et_id =(EditText)findViewById(R.id.et_id);
ll =(LinearLayout)findViewById(R.id.ll);}
public void add(View v){
db = oh.getWritableDatabase();
String name=et_name.getText().toString();
String sex=et_sex.getText().toString();
String department=et_department.getText().toString();
String salary=et_salary.getText().toString();
ContentValues values=new ContentValues();
values.put(“name”,name);
values.put(“sex”, sex);
values.put(“department”,department);
values.put(“salary”, salary);
db.insert(“staff”, null, values);
tv=new TextView(MainActivity.this);
tv.setText(“添加成功”);
db.close();} public void show(View v){
db = oh.getWritableDatabase();
Cursor cursor=db.query(“staff”, null, null, null, null, null, null, null);
while(cursor.moveToNext()){
String id=cursor.getString(cursor.getColumnIndex(“_id”));
String name=cursor.getString(cursor.getColumnIndex(“name”));
String sex=cursor.getString(cursor.getColumnIndex(“sex”));
String department=cursor.getString(cursor.getColumnIndex(“department”));
String salary=cursor.getString(cursor.getColumnIndex(“salary”));
tv=new TextView(MainActivity.this);
tv.setText(“ID:”+id+“;”+“Name:”+name+“;”+“Sex:”+sex+“;”+“Department:”+department+“;”+“Salary”+salary);
ll.addView(tv);
}
db.close();} public void clear(View v){
ll.removeAllViews();} public void deleteAll(View v){
db = oh.getWritableDatabase();
db.delete(“staff”, null, null);
tv=new TextView(MainActivity.this);
tv.setText(“刪除成功”);
db.close();}
public void deleteById(View v){
db = oh.getWritableDatabase();
String id=et_id.getText().toString();
db.delete(“staff”, “_id=?”, new String[]{id});
db.close();
tv=new TextView(MainActivity.this);
tv.setText(“ID刪除成功”);} public void findById(View v){
db = oh.getWritableDatabase();
String id=et_id.getText().toString();
Cursor cursor=db.query(“staff”, null, “_id=?”, new String[]{id}, null, null, null, null);
while(cursor.moveToNext()){
id=cursor.getString(cursor.getColumnIndex(“_id”));
String name=cursor.getString(cursor.getColumnIndex(“name”));
String sex=cursor.getString(cursor.getColumnIndex(“sex”));
String department=cursor.getString(cursor.getColumnIndex(“department”));
String salary=cursor.getString(cursor.getColumnIndex(“salary”));
tv=new TextView(MainActivity.this);
tv.setText(id+“;”+name+“;”+sex+“;”+department+“;”+salary);
ll.addView(tv);
tv=new TextView(MainActivity.this);
tv.setText(“ID查詢成功”);
}
db.close();} public void updateById(View v){
db = oh.getWritableDatabase();
String id=et_id.getText().toString();
String name=et_name.getText().toString();
String sex=et_sex.getText().toString();
String department=et_department.getText().toString();
String salary=et_salary.getText().toString();
ContentValues values=new ContentValues();
values.put(“name”,name);
values.put(“sex”, sex);
values.put(“department”,department);
values.put(“salary”, salary);
db.update(“staff”, values, “_id=?”, new String[]{id});
tv=new TextView(MainActivity.this);
tv.setText(“更新ID成功”);
db.close();} }
public class MyOpenHelper extends SQLiteOpenHelper {
public MyOpenHelper(Context context, String name, CursorFactory factory,int version){
super(context, name, factory, version);}
@Override
public void onCreate(SQLiteDatabase db){
db.execSQL(“create table staff(_id integer primary key autoincrement,name text,sex text,department text,salary float)”);}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){} }
五:運行結果截圖
實驗七:天氣預報 一:實驗目的
了解位置服務的概念;
了解地圖密鑰的申請方法;
掌握獲取地理信息的方法;
二:實驗設備
Eclipse 開發Android 應用 Android虛擬設備(AVD)
三:實驗內容
寫一個項目,實現顯示天氣預報的用戶界面,顯示已發送SMS短信的用戶界面,不同地區天氣的轉換
四:實驗核心代碼
package com.example.weather;
import java.io.BufferedReader;import java.io.InputStreamReader;import java.net.HttpURLConnection;import java.net.URL;import java.net.URLEncoder;import java.util.ArrayList;import java.util.List;
import net.sf.json.JSONArray;import net.sf.json.JSONObject;import android.app.Activity;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Bundle;import android.os.Handler;import android.os.IBinder;import android.os.Message;import android.view.View;import android.widget.ArrayAdapter;import android.widget.EditText;import android.widget.ImageView;import android.widget.ListView;import android.widget.TextView;import android.widget.Toast;
import com.zy.bean.Sms;import com.zy.bean.Weather;
public class MainActivity extends Activity { private MyConn conn = new MyConn();;private EditText et_city;private TextView tv_result;private ImageView iv_weather;private Handler handler;private Intent intent;private MyOpenHelper oh;private ServiceFunctions sFunctions;private MyArrayAdapter myArrayAdapter = null;private ListView lv;private int a = 1;private Weather weather;private List
@Override protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
oh = new MyOpenHelper(MainActivity.this, “weatherdemo.db”, null, 1);
// System.out.println(“數據庫創建完”);
et_city =(EditText)findViewById(R.id.et_city);
tv_result =(TextView)findViewById(R.id.tv_result);
iv_weather =(ImageView)findViewById(R.id.iv_weather);
lv =(ListView)findViewById(R.id.lv);
// System.out.println(“lv找到了”);
intent = new Intent(this, MyService.class);
startService(intent);
Toast.makeText(MainActivity.this, “服務啟動”, 0).show();
bindService(intent, conn, BIND_AUTO_CREATE);
Toast.makeText(MainActivity.this, “服務綁定”, 0).show();
handler = new Handler(new Handler.Callback(){
@Override
public boolean handleMessage(Message msg){
final Weather weather =(Weather)msg.obj;
tv_result.setText(weather.toString());
}
new Thread(new Runnable(){ @Override public void run(){
// TODO Auto-generated method stub
try {
URL url = new URL(weather.getDayPictureUrl());
HttpURLConnection con =(HttpURLConnection)url
.openConnection();
con.setRequestMethod(“GET”);
if(con.getResponseCode()== 200){
final Bitmap bitmap = BitmapFactory
.decodeStream(con.getInputStream());
runOnUiThread(new Runnable(){
}
@Override
public void run(){
// TODO Auto-generated method stub
iv_weather.setImageBitmap(bitmap);
}
});}
} catch(Exception e){
// TODO Auto-generated catch block e.printStackTrace();}
}).start();
return false;} });class MyConn implements ServiceConnection {
@Override public void onServiceConnected(ComponentName name, IBinder service){ sFunctions =(ServiceFunctions)service;} @Override public void onServiceDisconnected(ComponentName name){
} } class MyArrayAdapter extends ArrayAdapter
} public MyArrayAdapter(Context context, int resource,int textViewResourceId, List
sFunctions.insertInfo(weather, oh);
a++;} else {
sFunctions.updateInfoById(“1”, weather, oh);} Toast.makeText(MainActivity.this, “保存天氣信息成功”, 0).show();} public void show(View view){ smsList = sFunctions.findAll(oh);if(smsList.size()> 0){
List
for(Sms sms : smsList){
String s = sms.toString();
sList.add(s);
}
if(sList.size()> 0){
myArrayAdapter = new MyArrayAdapter(MainActivity.this,R.layout.second, R.id.tv_show, sList);
lv.setAdapter(myArrayAdapter);
} } }
public void getWeather(View view){
new Thread(new Runnable(){
String city = et_city.getText().toString();
@Override
public void run(){
try {
URL url = new URL(“http://api.map.baidu.com/telematics/v3/weather?location=”
+ URLEncoder.encode(city)
+ “&output=json&ak=QLZmpAbwFlWreQ28kLVgvKEC”);
HttpURLConnection con =(HttpURLConnection)url
.openConnection();
con.setRequestMethod(“GET”);
int code = con.getResponseCode();
if(code == 200){
BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
JSONObject json = JSONObject.fromObject(reader
.readLine());
// System.out.println(obj.toString());
JSONArray array = json.getJSONArray(“results”);
JSONObject obj = array.getJSONObject(0);
JSONObject weather_data = obj.getJSONArray(“weather_data”).getJSONObject(0);
weather = new Weather(obj.getString(“currentCity”), obj
.getString(“pm25”), weather_data
.getString(“date”), weather_data
.getString(“weather”), weather_data
.getString(“wind”), weather_data
.getString(“temperature”), weather_data
.getString(“dayPictureUrl”), weather_data
.getString(“nightPictureUrl”));
Message msg = new Message();
msg.obj = weather;
handler.sendMessage(msg);
}
} catch(Exception e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();} }
package com.example.weather;
import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper;
public class MyOpenHelper extends SQLiteOpenHelper {
public MyOpenHelper(Context context, String name, CursorFactory factory,int version){
super(context, name, factory, version);}
@Override public void onCreate(SQLiteDatabase db){
db.execSQL(“create table sms(_id integer primary key autoincrement,sms_sender text,sms_body text,sms_receive_time text,return_result text)”);
db.execSQL(“create table weatherinfo(_id integer primary key autoincrement,info text)”);}
@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
} }
package com.example.weather;
import java.util.List;
import android.app.Service;import android.content.Intent;import android.content.ServiceConnection;import android.os.Binder;import android.os.IBinder;
import com.zy.bean.Sms;import com.zy.bean.Weather;
public class MyService extends Service { private ISmsDaoImpl daoImpl;private MyBinder myBinder = new MyBinder();
@Override public IBinder onBind(Intent intent){
return myBinder;}
@Override public void unbindService(ServiceConnection conn){
super.unbindService(conn);}
class MyBinder extends Binder implements ServiceFunctions{
public long insertSms(Sms sms,MyOpenHelper oh){
return MyService.this.insertSms(sms,oh);
}
public List
return MyService.this.findAll(oh);
}
public long insertInfo(Weather w,MyOpenHelper oh){
return MyService.this.insertInfo(w,oh);
}
public int updateInfoById(String id, Weather w,MyOpenHelper oh){
return MyService.this.updateInfoById(id, w,oh);
} }
public long insertSms(Sms sms,MyOpenHelper oh){
daoImpl=new ISmsDaoImpl(oh);
long id = daoImpl.insertSms(sms);
return id;}
public List
daoImpl=new ISmsDaoImpl(oh);
List
return smsList;}
public long insertInfo(Weather w,MyOpenHelper oh){
daoImpl=new ISmsDaoImpl(oh);
long id = daoImpl.insertInfo(w);
return id;}
public int updateInfoById(String id, Weather w,MyOpenHelper oh){
daoImpl=new ISmsDaoImpl(oh);
int num = daoImpl.updateInfoById(id, w);
return num;} } 五:運行結果截圖
第五篇:最佳安卓游戲
2010 最易上癮游戲 最易上癮游戲 憤怒的小鳥 Angry Birds 瞄準射擊 shoot U!涂鴉切割 Slice It!碧湖垂釣 Fishin2 Go 涂鴉跳躍 Doodle Jump 重力滾球迷宮 Labyrinth 水果忍者 Fruit Ninja 扔紙團 Paper Toss 極限挑戰 The Impossible Game 炸毀 Blow up 物理空間 Space Physics 2010 最具人氣游戲 憤怒的小鳥 Angry Birds 會說話的湯姆貓 Talking Tom Cat 口袋傳奇 Pocket Legends 地牢守護者 Dungeon Defenders First Wave 和雛子一起做運動 一起高爾夫 2 Lets Golf 2 HD 會說話的圣誕老人 Talking Santa 植物大戰僵尸 3 細胞分裂 5 Splinter Cell Conviction HD 阿凡達 3D Avatar 天空的榮耀 Skies of Glory 2010 最具創意游戲 你畫我猜 What The Doodle 食物大合作 Spaghetti Marshmallows 繁忙的辦公室 Office Rush 小羊快跑 SheepRun 吉他 Guitar Solo 爆竹娃 Squibble 火箭兔子 Rocket Bunnies 扔紙團 Paper Toss 水果忍者 Fruit Ninja 涂鴉跳躍 Doodle Jump 2010 最佳競速游戲 都市賽車 5 Asphalt5 極品飛車 13 變速 Need For Speed:Shift 速度與激情之地下狂飆 Fast&Furious Adrenaline 魯莽賽車 Reckless Racing 3D 超音速飛行 TurboFly 3D 摩托大賽 Motorbike GP 瘋狂卡丁車 Krazy Kart Racing 穿山甲大冒險 Armadillo Roll
口袋賽車 PocketRacing 我的紙飛機 2 My Paper Plane2 2010 最佳塔防游戲 機器人塔防 Robo Defense 城堡勇士 Castle Warriors 槍之榮耀 Guns'n Glory 喪尸圍城 Grave defence 植物大戰僵尸 Plants vs Zombies 失落的戰役 Towser Defense 水晶塔防 Crystallight Defence 別惹惡魔 leave Devil alone 農夫大戰外星人 Rednecks vs Aliens 釘子戶大戰拆遷隊 2010 最佳對戰游戲 地牢守護者 Dungeon Defenders First Wave 天空的榮耀 Skies of Glory 狂野飆車 5 Asphalt5 迷你空中軍隊 Mini Squadron 三國殺 FIFA10 足球盛宴 EA FIFA 10 瘋狂卡丁車 Krazy Kart Racing 史瑞克 3D 賽車 Shrek Karting HD 2010 最佳益智游戲 涂鴉切割 Slice It 重力球迷宮 Labyrinth 超級跌落 Super tumble 炸毀 Blow up 軌道建設 X Construction 煉金術 Alchemy 飛機領航員 Flightfrenzy 功夫泡泡球 Bonsai Blast 俄羅斯方塊 Terris 景麗時間 Tangram Time 2010 最佳重力感應游戲 重力球迷宮 Labyrinth 保齡球 iBowl 穿山甲大冒險 Armadillo Roll 專業模擬飛行 X Plane Flight Simulator 碧湖垂釣 Fishin Go 涂鴉跳躍 Doodle Jump 小鐵球歷險記 Little Metal Ball 極限摩托車 MX Moto 3D 重力球完整版 Prism 3D 天生殺人狂之食人鯊 3D Hungry Shark
2010 最佳模擬經營游戲 模擬人生 3 The Sims 瘋狂農場 Farm Frinzy 美女餐廳 2 Diner Dash 游戲發展國 Game Dev Story 海盜餐廳 Barrr 口袋上帝 Pocket God 飯店大亨 Hotel Mogul 瘋狂壽司店 歡樂王國 Haypi kingdom 貨物管理員 Cargo 2010 最佳角色游戲 澤諾尼亞傳奇系列 ZENONIA 地牢守護者 Dungeon Defenders First Wave 蜘蛛俠 SpiderMan Tot
al Mayhem HD 地牢獵人 Dungeon Hunter 神秘傳說阿卡納 Legends Arcana 惡魔獵手 CaligoChaser 斯巴達英雄 Hero of Sparta 罪惡都市之西海岸的喧囂 Gangstar West Coast Hustle 2010 最佳體育游戲 最佳體育游戲 實況足球 2011 Real Soccer 2011 勁爆棒球 Homerun Battle 3D 高山滑雪 Big Mountain Snowboarding 超級棒球明星 2011 Baseball Superstars 2011 一起高爾夫 2 Lets Golf 2 HD 魔幻保齡球 Magic Bowling 3D 臺球大師 3d pool master 美式足球 Backbreaker Football 3D 投籃 Basketball Shots 3D 09 國際橄欖球賽 Rugby Nations09 手指任意球 Flick Kick Football 2010 最佳網游 口袋傳奇 Pocket Legends 明珠三國 2011 最值得期待游戲 植物大戰僵尸 Plants vs Zombies 割繩子 Cut the Rope