搜尋此網誌

2013-10-28

Context 是什麼?

作者:KH Chen

Context在很多地方都會用到,但是他到底有哪些限制?你現在拿到的Context真的是你想要的Context嗎?我們在開發APP常常會用到Context,但是在使用上我們卻常常忽略了一件事情:

One Context is not equal to another!!!

讓我們來看看下列表格:

ApplicationActivityServiceContentProviderBroadcastReceiver
Show a DialogNOYESNONONO
Start an ActivityNO1YESNO1NO1NO1
Layout InflationNO2YESNO2NO2NO2
Start a ServiceYESYESYESYESYES
Bind to a ServiceYESYESYESYESNO
Send a BroadcastYESYESYESYESYES
Register BroadcastReceiverYESYESYESYESNO3
Load Resource ValuesYESYESYESYESYES


從上述表格可以,在 Application、Activity…..等不同元件上所取得的上面的Context,能夠做哪些事情!

基本上,只有從Activity這邊拿到的Context是任何事情都能夠做的,也就是你的class A extend Activity後用getBaseContext()拿到的Context 是最萬能通用的!

三個常見的問題


1. 在呼叫dialog的時候,除了Activity拿到的Context,不要用其他地方拿到的Context去call一個dialog起來,會有問題的。

2. 當你要開啟另一個Activity的時候,雖然是都可以成功,但是除了Activity拿到的Context外,他是不建議這樣做的,因為會產生一些不正常的back stack behaviors 。

3. 在你要inflate layout的時候,要注意你的Context是不是Activity這邊拿到的,雖然其他地方拿到的也是可以執行,但是他會用system default 的theme去執行,而不是你在application中自己定義的theme。

結論:One Context is not equal to another


1. 不是所有的Context都是一樣的,當你宣告自己的manager去處理Context的傳遞的時候,要注意這件事情。

2. 盡量用Activity拿到的Context去做事情。


補充


1. 文章上說,Application context開dialog會有問題,可是android 提供這個 method: GsmServiceStateTracker.createManagedRoamingDialog()

發現 Service 也可以去使用 context / dialog 的情況,但是這受限於使用系統層級的 Dialog:
dialog.getWindow().setType((WindowManager.LayoutParams.TYPE_SYSTEM_ALERT));
2. 有些framework (network & CC)相關的檔案裡面,支援Context的global variable,而這個variable其實是從PhoneApp.java (Application來的) 意思是framework裡拿到的context 應是屬於Application context 。

3. 至於網路上所說的”不正常的back stack behavior”,這是因為android規定,如果是Application context 想要startActivity的話,必須加上一個” Intent.FLAG_ACTIVITY_NEW_TASK”,否則會有錯誤產生 (Exception)。可是這樣會造成每次畫面都是一個新的task 和新的相同 activity,這會延伸出令使用者困惑的不良設計。

Reference:http://www.doubleencore.com/2013/06/context/

沒有留言 :

張貼留言