一.Context是什么
開始學安卓的時候發現經常有context,但是都不知道為什么,什么時候需要它。
官方文檔概述:關於應用程序環境的全局信息的接口。這是一個抽象類,它的實現是由安卓系統提供的。它允許訪問應用程序特定的資源和類,以及應用級的操作,如啟動活動,電話,廣播和接收的意圖,等等。 我感覺可以把context比喻成一個游樂園,你要玩過山車,海盜船這些就要在游樂園中玩。
繼承關系
二.ContextWrapper與ContexImpl
ContextWrapper提供一系列方法。這樣繼承於它的Application,Service,Activitykey直接從它取得對應的方法。但是它的方法是空殼,具體功能由ContextImpl實現。
三.Application,Service,Activity
它們三者的對象就是一個context。因此在MainActivity中需要進行數據操作的時候的時候這樣寫
Editor editor = getSharedPreferences("Alarm", MODE_PRIVATE).edit();
但是在一個繼承於LinearLayout的子類中,則需要這樣寫
Editor editor = getContext().getSharedPreferences("Alarm", Context.MODE_PRIVATE).edit();
因此,在MainActivity中,有時候需要傳入Context的對象,可以看到直接用MainActivity.this 結合鬧鍾那個項目,在添加鬧鍾的時候
private void addAlarm(){ //添加一句輸出 Log.d("Context", getContext()+""); ... }
會發現這里的context是MainActivity
四.Context能力不一樣
文檔提到,可以通過context來進行多項操作,但是不同的Context能力范圍不一樣,游樂園也有大小區別嘛。
Conext能做的通用操作決定於這個context最初來源於哪里。下表所列的是,在應用中常見的會收到context對象的,以及對應的每種情況,它可以用於哪些地方:
- NO1 表示Application context的確可以開始一個Activity,但是它需要創建一個新的task。這可能會滿足一些特定的需求,但是在你的應用中會創建一個不標准的回退棧(back stack),這通常是不推薦的或者不是是好的實踐。
- NO2 表示這是非法的,但是這個填充(inflation)的確可以完成,但是是使用所運行的系統默認的主題(theme),而不是你app定義的主題。
- NO3 在Android4.2以上,如果Receiver是null的話(這是用來獲取一個sticky broadcast的當前 值的),這是允許的。
這可以結合安卓的那個鬧鍾項目
public class AlarmReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub ... Log.d("Context", getContext()+""); //啟動響鬧鍾的界面 Intent i = new Intent(context, PlayMusic.class); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(i); } }
可以發現這里的Context是ReceiverRestrictedContext,因此需要創建一個新的task