星期六, 8月 27, 2011

進程與執行緒Processes and Thread

Andoird應用程式筆記

今天試著了解運行應用程式的process與thread。

當一個應用程式的組件開始運行且任何其他應用程式組件都沒有在運行時,android系統為執行有一執行續的應用程式啟動一個新的linux進程。預設為同一應用程式的所有組件會運行在同一進程與執行續中。如果有一應用程式組件啟動而應用程式已存在於進程(因為其他應用程式組件已存在),組件會被啟動在相同的進程與執行緒中。然而你可以分配應用程式中的組件運行於不同進程中,且你可以在任何進程中增加執行續。

Processes(以下稱作"進程")

預設為同應用程式的所有組件運行於同一進程中,而大部分應用程式不應該改變這個預設狀態。然而,如果你發現你必須控制屬於一些組件的進程,你可以在manifest檔案中做到。

manifest檔案中為每種組件的元件,<activity>、<service>、<reciever>與<provoder>支援一個android:process屬性指定組件可以運行在進程。你可以設定這一屬性讓每個組件擁有自己的進程或者一些組件分享一個進程。你也可以設定android:process讓不同應用程式的組件運行在一個進程中。

<application>元件也支援android:process屬性去設定一個預設值應用在所有組件。

android可能在一些點會決定關閉進程,當記憶體不夠與其他必須立即服務使用者的組件的要求。運行應用程式組件的進程被殺掉後,應用程式因此被銷毀。當有要為組件工作時,進程再次為這些組件啟動。

當決定哪些進程要殺掉後,android系統權重它們對使用者的重要性。例如系統更容易關閉一個主持已不再顯示在螢幕的activity組件的進程,比起主持顯示在螢幕的activity組件的進程。根據組件運行在進程中的狀態決定是否終結進程。以下是一些終結進程的原則討論。

Process lifecycle
android系統試著維護應用程式進程盡可能的久,但是即使如此仍需要為新的或更重要的進程移除舊的進程回收記憶體。決定那些進程保留那些殺掉,系統根據組件運行在進程中的狀態將每個進程放置到"importance hierachy"中。較不重要的進程會最先被移除,如此繼續,當有需要回復系統資源時。

在importance hierachy中有五層,以下列出不同型態的進程的重要性(第一個型態進程是最重要也是最晚被殺掉的)。

1.Foreground process
進程是被當前使用者需要的。進程如果在以下情況被人為是foreground的:

  • 它主持一個正在與使用者互動的Activity(Activity的onResume()方法已經被呼叫)。
  • 它主持一個綁定正在與使用者互動的Actvity的Service。
  • 它主持一個正在"前台"運行的Service,Service已經呼叫startForeground()。
  • 它主持一個正在執行生命週期中的其中一個回呼的Service(onCreate()、onStart()、onDestory())。
  • 它主持一個正在執行onReceive方法的BroadReveiver。
通常,只有少數foreground processes存在於任何給定的時間。它們只在如果記憶體低到所有foreground processes無法繼續運行時被殺掉為最後手段。通常如果走到這一步,會殺掉一些foreground processes以便保持使用者介面的回應。

2.Visible process
進程沒有任何前台組件,但是仍能影響使用者在螢幕上所看到的事。如果以下條件其中一個為真,進程被認為是visible process:

  • 它主持一個不是foreground的Activity,但是仍然是對使用者是可見的(onPause()方法已經被呼叫)。這樣情況有可能發生,例如,如果前台activity組件啟動一個對話,在前台activity組件背後的前一個activity組件允許被看見。
  • 它主持一個綁定在可見(前台)的activity上的service。
visible process被認為是非常重要的且不會被殺掉,除非殺掉進程可以保持前台進程繼續運行。

3.Service process
進程正在運行一個已被startService()啟動的Service且進程不是前面兩個更高的類別。雖然service process無法直接給任何使用者看見,它們通常做的事是使用者在意的,例如播放背景音樂或從網路下載資料,所以系統保持它們運行,除非沒有足夠的記憶體保留它們。

4.Background process
進程正保存一個使用者近期看不見的activity組件(activity的onStop()已經被呼叫)。這些進程對於使用者經驗沒有直接的影響,而且系統能在任何時間為foreground、visible或service進程回收記憶體。通常系統會有許多background進程在運行,所以它們被保存在LRU列去確保最近被使用者看見的進程在最後殺掉。如果activity組件正確地執行生命週期而且保留目前狀態,殺掉進程對使用者經驗不會有明顯影響,因為當使用者導航回到activity組件時,activity組件會恢復所有可見狀態。
5.Empty process
這個進程沒有保有任何應用程式組件。保留這種進程的唯一原因是為了緩存的目的,以便改善下次組件需要在近程運行時的啟動時間。系統通常會殺掉這些進程來平衡整體系統資源進程暫存與核心暫存之間。

android盡可能將進程排序在最高階層,根據目前在進程中運行的組件的重要性。例如,如果進程主持一個service和visible組件,進程會被排序在visible process類別中,不是service process中。

此外,進程階層可能被提升,因為其他的進程要依賴它,一個服務其他進程的進程從不會排在比他服務的進程更低的階層。例如,如果在進程A的content provider服務在進程B中的客戶端,或如果在進程A的service被在進程B中的組件綁定,進程A總是被認為至少與進程B一樣重要。

星期五, 8月 26, 2011

The AndroidManifest File

Android應用程式學習筆記

在開啟專案後,會在專案檔案目錄中發現一個AndroidManifest.xml檔案,這一個檔案存有甚麼意義呢?

在android系統開始執行應用程式之前,系統必須知道應用程式存在哪些組件,因此android系統透過讀取應用程式的AndroidManifest.xml檔案(The "manifest" file)得知。應用程式必須在這個檔案裡宣告所有應用程式使用的組件,此檔案必須在應用程式的根目錄中。

Manifest檔案增加宣告應用程式組件的事:

  • 識別任何應用程式要求的使用者權限,例如網路存取或者唯讀使用者聯絡人。
  • 根據應用程式需求的API宣告最小API層級。
  • 宣告應用程式需要或使用的硬體或軟體,例如攝影機、藍芽服務或者多點觸控。
  • 應用程式需要的API函式庫。
  • 等等更多。


那該如何在manifest檔案中宣告四種應用程式組件:

manifest檔案其中主要的任務是告知系統應用程式用到的組件。例如在manifest檔案宣告一個activity組件。


<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:icon="@drawable/app_icon.png" ... >
        <activity android:name="com.example.project.ExampleActivity"
                  android:label="@string/example_label" ... >
        </activity>
        ...
    </application>
</manifest>


<application>元件中,android:icon屬性指出識別應用程式的icon的來源。
<activity>元件中,android:name屬性指定Activity的完全合格類別名稱;屬性為activity指定字串給使用者的標籤。


所有應用程式組件都必須用這方式宣告:

  • Activity組件用<activity>元件
  • Service組件用<service>元件
  • Broadcast receiver組件用<receiver> 元件
  • content provider組件用<provider> 元件


星期二, 8月 23, 2011

激活組件

Android應用程式筆記

四種組件中的三種組件activities、services和broadcast receivers可以受不同步訊息intent激活,intent與組件在運行時彼此綁定,不管這個組件是屬於你的應用程式或者其他應用程式。

intent由Intent類別產生,Intent類別定義激活特定組件或者特定類型組件的消息,一個intent可以是明確的也可以是隱含的。

對於activities與services,intent定義一些行為去激活,例如"view"或者"send"一些東西,且可能指定資料的URI去激活。例如intent傳遞要求給activity,讓activty顯示圖片或者開啟網頁。在一些案例中,你可以啟動activty接收結果,以此為例,這個activity也可用intent回傳結果,例如你可以發出一個intent讓使用者選個人聯絡人回傳給你,回傳的intent包含一個指向所選定聯絡人的URI。

對於broadcast receivers,intent簡單定義公告當作廣播,例如標明裝置電池為低電量的廣播只包含"battery is low"的已知操作字串。

其他組件型態,content provider,不會被intent激活。而從ContentResolver來的要求才會激活content provider。content resolver處理所有與content provider的直接交易,所以用provider執行交易的組件不需要呼叫ContentResolver方法。這留下一層content provider與組件之間要求訊息的抽象層。

以下有激活各個組件不同的方法:

  • 你可以傳遞intent到startActivity()或者startActivityForResult()(如果你希望activty回傳結果)來啟動activty(或給他一些新的任務去做)。
  • 你可以傳遞intent到startService()來啟動service(或給正在進行的service新指令)。或者你可以傳遞intent到bindService()來綁定service。
  • 你可以傳遞intent到sendBroadcast()、sendOrderedBroadcast()或者sendStickyBroadcast()來初始一個廣播。
  • 你可以呼叫ContentResolver上的query()執行查詢content provider。



星期一, 8月 22, 2011

組件

Android應用程式筆記


Android應用程式組件是在建置應用程式相當重要的元素,系統可以通過不同組件進入應用程式,並不是所有組件都有給使用者進入應用程式實際方式,而是依靠其他組件,每一個組件擁有各自獨特的功能幫助建置應用程式的行為。

Android有四種不同的應用程式組件,每一組建有分明的功能和生命週期,以下是四種組件的簡單介紹:

Activities
一個activity顯示一個使用者介面。例如電子郵件應用程式可能會有一個activity顯示所有未閱讀的電子郵件,另一個activity顯示撰寫電子郵件,另一個activity顯示閱讀電子郵件。雖然這些activities一起運作拚合成使用者使用電子郵件應用程式的經驗,但是activity之間是互相獨立的。其他應用程式也可以啟動電子郵件應用程式中的任何一個activity,只要電子郵件應用程式允許。例如攝影應用程式啟動電子郵件應用程式中的撰寫新郵件的activity,去分享攝影的圖片。
Services
一個service是運行在後台執行長時間運行的服務或為遠端執行續執行的組件。service不提供使用者介面,因此使用者並不能直接使用service組件。例如service可能是當使用者使用不同應用程式時在後台播放音樂的service組件,或者可能是不會干擾使用者與activity互動下從網路取得資料的service組件。其他的組件可以啟動service或者綁定service與它互動。
Content providers
一個content provide管理一組應用程式分享的資料。我們可以將資料存在檔案系統、SQLite資料庫、網路上、或者任何應用程式可以存取的本地持久性存儲,透過content provider可以查詢或者甚至修改資料。例如andoird系統提供一個content provider管理使用者聯絡人的資訊,因此任何有適合權限的應用程式都可以查詢content provider的部分去讀寫聯絡人資訊。
content provier也可用來讀寫應用程式私有不分享的資料,例如Note Pad應用程式使用content provider存下筆記。
Broadcast receivers
Broadcast receiver組件負責回應全系統廣播的公告。許多廣播來自系統,如廣播公告螢幕即將被關閉、電量過低、或者圖片被截取。應用程式也可以初始廣播,如通知其他應用程式知道有一些資料已經下載到裝置,它們可以使用了。雖然broadcast不會顯示使用者介面,他們可以當廣播事件發生時創造狀態列警告去告知使用者。更常見地,broadcast receiver是到其他組件的一種"管道"。

Android系統設計的獨特方面是任何應用程式可以啟動其他應用程式的組件。例如如果你希望使用者用攝影裝置擷取一張相片,有可能其他應用程式可以做到,然後你的應用程式可以使用它來代替自己開發一個activity去擷取相片,你無須合併或甚至連接來自攝影機應用程式的程式碼。反而你可以簡單啟動在攝影機應用程式的activity去擷取相片。當完成擷取後,相片回傳到你的應用程式使用。對於使用者,這樣的方式攝影機似乎就是你的應用程式的一部份。

當系統啟動組件時,系統為應用程式啟動執行續及實作組件需要的類別。例如你的應用程式啟動在攝影機應用程式中的activity去擷取相片,那個activity運行在攝影機應用程式之下,並不是在你的應用程式執行續中。因此,不像其他大部分的應用程式,android應用程式沒有單一進入點(沒有main()方式)。

因為系統運行每一個應用程式於個別有檔案權限的執行續中以限制存取其他應用程式,你的應用程式無法直接激活其他應用程式的組件。然而android系統可以,所以激活其他應用程式的組件,你必須傳送訊息給系統,並指定你的intent給特定組件,然後系統幫你激活其他組件。

感謝大家閱讀,如有錯誤歡迎指教,謝謝。

星期日, 8月 21, 2011

Android應用程式基礎

Android應用程式筆記

先我們從android適用甚麼樣的程式語言編寫的開始,所有Android應用程式以Java程式語言撰寫,應用程式程式碼包括任何資料和資源檔案經由Android SDK編譯為一個Android package,編譯後以.apk為檔案,而一個.apk檔案就是一個我們在行動裝置上使用的應用程式,.apk可以安裝在任何以android為作業系統的裝置上。一旦應用程式安裝到裝置上會有以下幾個安全性特性:
  • Android作業系統是一個多用戶linux系統,應用程式之間彼此是不同的用戶;
  • 系統分配每個應用程式一個唯一的linux使用著ID,這個ID只有系統知道,應用程式並不知道,系統為每個應用程式中所有的檔案設定權限,因此只有被分配到使用者ID的應用程式可以使用系統中的資源;
  • 每個進程(process)擁有各自的虛擬機器,因此應用程式與應用程式彼此之間是互相隔離的;
  • 每個應用程式運行在自己的linux執行緒中。當任何一個應用程式的元件需要被執行時,android便會自動啟動執行續,然後在元件不再需要時或者系統必須為其他應用程式回收記憶體時會關閉執行續。
在這種方式下android落實了最小許可權原則,每個應用程式只能在元件需要時才會允許存取系統資源,如此創造一個非常安全的環境,應用程式無法在沒有權限下存取系統的任何部分,保護系統避免受到錯誤或惡意程式的破壞。

然而,還是有一些方法讓應用程式之間分享資料以及存取系統服務:
  • 安排兩個應用程式分享同一個linux使用者ID是可能的,如此這兩個應用程式就可以存取彼此的檔案。為保護系統資源,有相同linux使用者ID的應用程式也可以安排運行相同的linux執行緒中及分享相同的虛擬機器。
  • 應用程式可以要求存取裝置資料的權限,如使用者聯絡人、SMS 訊息、可安裝存儲(SD card)、攝影機、藍芽等等。這些應用程式權限必須在使用者安裝時就授予。


感謝大家閱讀,如有錯誤歡迎指教,謝謝。

星期六, 8月 20, 2011

Android架構

今天跟大家分享自學的Android架構的知識筆記
以下是從官網節錄下來的架構圖
Android架構分成Application、Application Framwork、Libraries、Android Runtime、Linux Kernel。


看完架構圖之後,現在就依照各部分簡單說明。

Application:
應用層簡單說明就是我們在手機裝置或移動裝置上使用到的所有應用程式與其他功能,包括email client、SMS program、日曆、地圖、瀏覽器、聯絡人等等,都是屬於應用層。所有的應用程式皆由Java程式語言撰寫。
Application Framework:
應用架構層簡單說明是提供應用程式開發員開放開發平台,開發員可以自由使用裝置硬體、存取本地資訊、運行背景服務、設定鬧鐘、增加狀態列等等的優點。所有應用程式底層由幾個服務與系統組成,包括View、Content providers、Resourse manager、Notification manager、Acticity manager。View中包含豐富建立應用程式畫面的元件,如按鈕、lists、grids、甚至可嵌入的網頁瀏覽器;Content provider使應用程式能夠存取來自其他應用程式的資料,或者分享自己的資料給其他應用程式;Resourse manager提供存取非代碼的資源,如本地化的字串、圖片、layout files;Notification manager使所有應用程式能夠在狀態列上顯示一些自定義的警報訊息;、Acticity manager管理應用程式的生命週期。
Libraries:
Libraries是一組C/C++函式庫,這些函式庫被android系統各個元件使用,而這些元件功能通過android framework給應用程式開發者加以使用。一些核心函式庫包括System C library、Media libraries、Surface manager、LibWebCore、SGL、3D libraries、FreeType、SOLite。Media libraries基於PacketVideo的OpenCORE,函式庫支持播放和錄音許多影音格式,包含MPEG4、H.264、MP3、AAC、JPG和PNG;SGL為2D圖形引擎;3D libraries執行基於OpenGL ES 1.0 APIs;SOLite功能強大的關聯式資料庫。
Android Runtime:
每一個Android的應用程式運行在自己的Dalvik虛擬機器及執行緒中。
Linux:
android底層是Linux 2.6版本為核心系統。

認識android架構後,對於開發者有甚麼好處呢?個人是覺得如果是想開發應用程式的話,一定要把application與application framework摸熟,因為應用程式只要使用這兩層完成的;如果是想開發嵌入式程式就要多多把更底層的libraries和android runtime等摸熟了,自己也剛開始學習android,歡迎大家指教囉。

以上就是android架構的簡單介紹,希望讀者能對android架構有初步認識,其中如有錯誤還請各位指教,感謝閱讀。

星期四, 8月 11, 2011

onClick(View v)方法

新的onClick()方法發生錯誤
新的onClick(View v)方法是不需要使用"button監聽器"來判斷按鈕是否被按下
而是當按鈕被按下後直接呼叫該按鈕的方法
並執行裡面的程式運算動作
這樣的方式可以避免一個情況
假如應用程式中有10個按鈕
每個按鈕都產生一個監聽器
就要產生10個按鈕監聽器
無論按鈕是否被按下
因此我在篇寫程式時都是用新的方式
但是今天在模擬器上跑自己的應用程式
發現如果用新的onClick()方法竟然造成錯誤而強制終止應用程式
不知道是甚麼原因造成的
還真讓人頭痛!
好想知道為什麼喔!