Context在很多地方都會用到,但是他到底有哪些限制?你現在拿到的Context真的是你想要的Context嗎?我們在開發APP常常會用到Context,但是在使用上我們卻常常忽略了一件事情:
One Context is not equal to another!!!
讓我們來看看下列表格:
Application | Activity | Service | ContentProvider | BroadcastReceiver | |
---|---|---|---|---|---|
Show a Dialog | NO | YES | NO | NO | NO |
Start an Activity | NO1 | YES | NO1 | NO1 | NO1 |
Layout Inflation | NO2 | YES | NO2 | NO2 | NO2 |
Start a Service | YES | YES | YES | YES | YES |
Bind to a Service | YES | YES | YES | YES | NO |
Send a Broadcast | YES | YES | YES | YES | YES |
Register BroadcastReceiver | YES | YES | YES | YES | NO3 |
Load Resource Values | YES | YES | YES | YES | YES |
從上述表格可以,在 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/
沒有留言 :
張貼留言