顯示具有 activity 標籤的文章。 顯示所有文章
顯示具有 activity 標籤的文章。 顯示所有文章

2011年12月28日 星期三

Android - ANR出現的時機

ANR詳細說明請參考官網,會出現ANR的2個時機是

(1)程式對使用者的輸入(按實體按鍵或是螢幕),超過5秒沒有反應

(2)BroadReceiver超過10秒還沒結束。

BroadReceiver 因為這個特性,所以不應該在收到Broadcast後做太多費時的工作。正確在收到Receiver後,service或是透過notification 去執行就要去執行某個activity....等其他相對應的工作。注意,不要直接執行activity而要透過notification,讓使用者自行 決定是否要去執行activity。否則activity忽然跑出來螢幕上會讓使用者原本操作的程式被中斷,這是不好的使用者操作經驗,要適情況避免!

避免ANR並給使用者好的操作方式 ,建議三點:
(1)呈現等待的畫面 (例如: progress bar)
(2)使用子線程
(3) 如果是在程式初始畫面即有大量運算或等待的情況時,要用asynchronously的方式來改變UI。舉例來說程式一開始執行時會透過網路下載30張小 圖片到畫面上時,可以每下載一張圖片完成,就先把這張圖片秀到畫面上,而不是30張都下載完了才一口氣全部秀到畫面上。

Android - Activity設計建議(2)

(6)如果你的activity會送資料給其它程式,應該設計一個選項讓user知道。利如Gallery會有Share的功能,按下後可以把資料 送給Facebook,Mail,Messages,Twitter....等。這個時候要特別注意建議(2)有可能發生的錯誤。當想要啟動一個 Activity時,如果會再次返回原Activity並得到一些資料,可以使用startActivityResult()。如果不需要在返回時取得資 料就可以用startActivity()


(7)你的Activity可以依特殊需求設計成Widget,而且Widget除了可以放在Home上面之外,也可以放在其它的application上,如果一來可以依需求不停的update內容。


(8) 如果你的Activity會被其它application執行,為了讓activity不會影響該application返回(按下return key)的行為,launch mode盡量使用standard 或 singleTop 而不要使用 singleTask or singleInstanc。Launch mode四者的差別請參考http://slashgill.blogspot.com/search/label/launchMode


(9) 當使用者由Activity A 按下notification到Activity B後,若按下 Back Key 時應該要能正確返回 Activity A。這時候為了避免Activity B按下Back Key會執行該application的其它activity(如果這些activity曾被執行而留在activity stack裡面的話),因此要把Activity B的taskAffinity設定空字串(不可以不設定)


(10)相較於上面的另一種作法是用在執行Activity B的時候,先設定FLAG_ACTIVITY_CLEAR_TOP和ACTIVITY_NEW_TASK,這樣到時候從Activity B按下Back Key時,就會回到Activity A


(11)盡可能不要改變Back Key的行為,才不會影響使用者原本的操作習慣。

Android - Activity設計建議(1)

有關設計建議的詳細內容請參考官網說明

(1)如果你的activity只想被自己設計的application使用,而不想被別的application使用,那就不要建立intent filter,直接使用explicit intents,例如:

   Intent it = new Intent();
   it.setClass(this,MyActivity.class);
   startActivity(it);

這樣就沒有別的applicaton會因為誤發了一個intent而把MyActivity給執行起來。使用intent filter會發佈到Android系統上,讓別的application也有機會執行。


(2)使用intent要特別注意,如果這個intent要呼叫的apk是第三方程式(意即可能被移除),那startActivity()很有可能會產生Exception。兩種解決方式

   (1) try{
           startActivity();
       }catch(ActivityNotFoundException e){
           //do something if the apk is uninstalled
       }

   (2) 利用package manager確定這個apk是否還在Android裝置裡面,做法可參考這篇文章



(3)如果你的Activity可以單獨執行,應該讓使用者在Launcher可以執行它。也就是application中應該有一個activity要有
            <intent-filter>
                <action android:name="android.intent.action.MAIN"></action>
                <category android:name="android.intent.category.DEFAULT"></category>
            </intent-filter>



(4)相較於上者,如果你有一個不常用的小程式,尤其是系統內也內建有類似功能的程式,或者這個小程式是依附在其他程式底下,那也許不用大費周章的為他在Launcher設立一個可以執行的icon。只要有intent filter可以在適當的時候被呼叫起來就好了。



(5) 相較於(3)和(4),如果你有兩支activity可獨立執行,但是有很多資料、程式碼是可以共用的,那可以考慮寫成一支application但是有 兩個可以在Launcher執行的icon,像是Camera 和 Camcorder。在AndroidManifest.xml中,這兩支activity都有

                  <action android:name="android.intent.action.MAIN" />
                  <category android:name="android.intent.category.DEFAULT" />

但是要注意的是要把taskAffinity分開,兩者才不會互相影響。例如
android:taskAffinity="android.task.camera" 和 android:taskAffinity="android.task.Camcorder",

有關taskAffinity可以參考官網的說明