青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

life02

  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
  197 隨筆 :: 3 文章 :: 37 評論 :: 0 Trackbacks

轉載必須注明出處 :http://blog.csdn.net/qinjuning

 

 

             前言:本文是我讀《Android內核剖析》第7章 后形成的讀書筆記 ,在此向欲了解Android框架的書籍推薦此書。

 

 

 

 

        大家好,  今天給大家介紹下我們在應用開發中最熟悉而陌生的朋友-----Context類 ,說它熟悉,是應為我們在開發中

   時刻的在與它打交道,例如:Service、BroadcastReceiver、Activity等都會利用到Context的相關方法 ; 說它陌生,完全是

   因為我們真正的不懂Context的原理、類結構關系。一個簡單的問題是,一個應用程序App中存在多少個Context實例對象呢?

   一個、兩個? 在此先賣個關子吧。讀了本文,相信您會豁然開朗的 。

 

      Context,中文直譯為“上下文”,SDK中對其說明如下:

         Interface to global information about an application environment. This is an abstract class whose implementation

  is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls 

  for application-level operations such as launching activities, broadcasting and receiving intents, etc

 

    從上可知一下三點,即:

        1、它描述的是一個應用程序環境的信息,即上下文。

        2、該類是一個抽象(abstract class)類,Android提供了該抽象類的具體實現類(后面我們會講到是ContextIml類)。

        3、通過它我們可以獲取應用程序的資源和類,也包括一些應用級別操作,例如:啟動一個Activity,發送廣播,接受Intent

      信息 等。。

 

 

   于是,我們可以利用該Context對象去構建應用級別操作(application-level operations) 。

 

 一、Context相關類的繼承關系

 

                         

 

  相關類介紹:

 

   Context類    路徑: /frameworks/base/core/java/android/content/Context.java

            說明:  抽象類,提供了一組通用的API。

      源代碼(部分)如下:   

  1. public abstract class Context {  
  2.      ...  
  3.      public abstract Object getSystemService(String name);  //獲得系統級服務  
  4.      public abstract void startActivity(Intent intent);     //通過一個Intent啟動Activity  
  5.      public abstract ComponentName startService(Intent service);  //啟動Service  
  6.      //根據文件名得到SharedPreferences對象  
  7.      public abstract SharedPreferences getSharedPreferences(String name,int mode);  
  8.      ...  
  9. }  

 

  ContextIml.java類  路徑 :/frameworks/base/core/java/android/app/ContextImpl.java

          說明:該Context類的實現類為ContextIml,該類實現了Context類的功能。請注意,該函數的大部分功能都是直接調用

      其屬性mPackageInfo去完成,這點我們后面會講到。    

         源代碼(部分)如下:

  1. /** 
  2.  * Common implementation of Context API, which provides the base 
  3.  * context object for Activity and other application components. 
  4.  */  
  5. class ContextImpl extends Context{  
  6.     //所有Application程序公用一個mPackageInfo對象  
  7.     /*package*/ ActivityThread.PackageInfo mPackageInfo;  
  8.       
  9.     @Override  
  10.     public Object getSystemService(String name){  
  11.         ...  
  12.         else if (ACTIVITY_SERVICE.equals(name)) {  
  13.             return getActivityManager();  
  14.         }   
  15.         else if (INPUT_METHOD_SERVICE.equals(name)) {  
  16.             return InputMethodManager.getInstance(this);  
  17.         }  
  18.     }   
  19.     @Override  
  20.     public void startActivity(Intent intent) {  
  21.         ...  
  22.         //開始啟動一個Activity  
  23.         mMainThread.getInstrumentation().execStartActivity(  
  24.             getOuterContext(), mMainThread.getApplicationThread(), null, null, intent, -1);  
  25.     }  
  26. }  

 


 

  ContextWrapper類 路徑 :\frameworks\base\core\java\android\content\ContextWrapper.java

        說明: 正如其名稱一樣,該類只是對Context類的一種包裝,該類的構造函數包含了一個真正的Context引用,即ContextIml

       對象。    源代碼(部分)如下:

  1. public class ContextWrapper extends Context {  
  2.     Context mBase;  //該屬性指向一個ContextIml實例,一般在創建Application、Service、Activity時賦值  
  3.       
  4.     //創建Application、Service、Activity,會調用該方法給mBase屬性賦值  
  5.     protected void attachBaseContext(Context base) {  
  6.         if (mBase != null) {  
  7.             throw new IllegalStateException("Base context already set");  
  8.         }  
  9.         mBase = base;  
  10.     }  
  11.     @Override  
  12.     public void startActivity(Intent intent) {  
  13.         mBase.startActivity(intent);  //調用mBase實例方法  
  14.     }  
  15. }  

 


 

   ContextThemeWrapper類 路徑:/frameworks/base/core/java/android/view/ContextThemeWrapper.java

      說明:該類內部包含了主題(Theme)相關的接口,即android:theme屬性指定的。只有Activity需要主題,Service不需要主題,

   所以Service直接繼承于ContextWrapper類。

      源代碼(部分)如下:

  1. public class ContextThemeWrapper extends ContextWrapper {  
  2.      //該屬性指向一個ContextIml實例,一般在創建Application、Service、Activity時賦值  
  3.        
  4.      private Context mBase;  
  5.     //mBase賦值方式同樣有一下兩種  
  6.      public ContextThemeWrapper(Context base, int themeres) {  
  7.             super(base);  
  8.             mBase = base;  
  9.             mThemeResource = themeres;  
  10.      }  
  11.   
  12.      @Override  
  13.      protected void attachBaseContext(Context newBase) {  
  14.             super.attachBaseContext(newBase);  
  15.             mBase = newBase;  
  16.      }  
  17. }  

 

 

     Activity類 、Service類 、Application類本質上都是Context子類, 更多信息大家可以自行參考源代碼進行理解。

 

 

二、 什么時候創建Context實例 

 

      熟悉了Context的繼承關系后,我們接下來分析應用程序在什么情況需要創建Context對象的?應用程序創建Context實例的

 情況有如下幾種情況:

      1、創建Application 對象時, 而且整個App共一個Application對象

      2、創建Service對象時

      3、創建Activity對象時

 

    因此應用程序App共有的Context數目公式為:

 

                     總Context實例個數 = Service個數 + Activity個數 + 1(Application對應的Context實例)

 

  具體創建Context的時機

 

     1、創建Application對象的時機

 

       每個應用程序在第一次啟動時,都會首先創建Application對象。如果對應用程序啟動一個Activity(startActivity)流程比較

清楚的話,創建Application的時機在創建handleBindApplication()方法中,該函數位于 ActivityThread.java類中 ,如下:

  1. //創建Application時同時創建的ContextIml實例  
  2. private final void handleBindApplication(AppBindData data){  
  3.     ...  
  4.     ///創建Application對象  
  5.     Application app = data.info.makeApplication(data.restrictedBackupMode, null);  
  6.     ...  
  7. }  
  8.   
  9. public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {  
  10.     ...  
  11.     try {  
  12.         java.lang.ClassLoader cl = getClassLoader();  
  13.         ContextImpl appContext = new ContextImpl();    //創建一個ContextImpl對象實例  
  14.         appContext.init(this, null, mActivityThread);  //初始化該ContextIml實例的相關屬性  
  15.         ///新建一個Application對象   
  16.         app = mActivityThread.mInstrumentation.newApplication(  
  17.                 cl, appClass, appContext);  
  18.        appContext.setOuterContext(app);  //將該Application實例傳遞給該ContextImpl實例           
  19.     }   
  20.     ...  
  21. }  

 

 

    2、創建Activity對象的時機

 

       通過startActivity()或startActivityForResult()請求啟動一個Activity時,如果系統檢測需要新建一個Activity對象時,就會

  回調handleLaunchActivity()方法,該方法繼而調用performLaunchActivity()方法,去創建一個Activity實例,并且回調

 onCreate(),onStart()方法等, 函數都位于 ActivityThread.java類 ,如下:

  1. //創建一個Activity實例時同時創建ContextIml實例  
  2. private final void handleLaunchActivity(ActivityRecord r, Intent customIntent) {  
  3.     ...  
  4.     Activity a = performLaunchActivity(r, customIntent);  //啟動一個Activity  
  5. }  
  6. private final Activity performLaunchActivity(ActivityRecord r, Intent customIntent) {  
  7.     ...  
  8.     Activity activity = null;  
  9.     try {  
  10.         //創建一個Activity對象實例  
  11.         java.lang.ClassLoader cl = r.packageInfo.getClassLoader();  
  12.         activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);  
  13.     }  
  14.     if (activity != null) {  
  15.         ContextImpl appContext = new ContextImpl();      //創建一個Activity實例  
  16.         appContext.init(r.packageInfo, r.token, this);   //初始化該ContextIml實例的相關屬性  
  17.         appContext.setOuterContext(activity);            //將該Activity信息傳遞給該ContextImpl實例  
  18.         ...  
  19.     }  
  20.     ...      
  21. }  

 

 

   3、創建Service對象的時機

 

       通過startService或者bindService時,如果系統檢測到需要新創建一個Service實例,就會回調handleCreateService()方法,

 完成相關數據操作。handleCreateService()函數位于 ActivityThread.java類,如下:

  1. //創建一個Service實例時同時創建ContextIml實例  
  2. private final void handleCreateService(CreateServiceData data){  
  3.     ...  
  4.     //創建一個Service實例  
  5.     Service service = null;  
  6.     try {  
  7.         java.lang.ClassLoader cl = packageInfo.getClassLoader();  
  8.         service = (Service) cl.loadClass(data.info.name).newInstance();  
  9.     } catch (Exception e) {  
  10.     }  
  11.     ...  
  12.     ContextImpl context = new ContextImpl(); //創建一個ContextImpl對象實例  
  13.     context.init(packageInfo, null, this);   //初始化該ContextIml實例的相關屬性  
  14.     //獲得我們之前創建的Application對象信息  
  15.     Application app = packageInfo.makeApplication(false, mInstrumentation);  
  16.     //將該Service信息傳遞給該ContextImpl實例  
  17.     context.setOuterContext(service);  
  18.     ...  
  19. }  


 

    另外,需要強調一點的是,通過對ContextImp的分析可知,其方法的大多數操作都是直接調用其屬性mPackageInfo(該屬性類

型為PackageInfo)的相關方法而來。這說明ContextImp是一種輕量級類,而PackageInfo才是真正重量級的類。而一個App里的

有ContextIml實例,都對應同一個packageInfo對象。

            

 

     最后給大家分析利用Context獲取SharedPreferences類的使用方法,SharedPreferences類想必大家都使用過,其一般獲取方

法就是通過調用getSharedPreferences()方法去根據相關信息獲取SharedPreferences對象。具體流程如下:

 

    1 、調用  getSharedPreferences()獲取對應的的文件,該函數實現功能如下:

 

  1. //Context類靜態數據集合,以鍵值對保存了所有讀取該xml文件后所形成的數據集合  
  2. private static final HashMap<File, SharedPreferencesImpl> sSharedPrefs =   
  3.        new HashMap<File, SharedPreferencesImpl>();   
  4.   
  5. @Override  
  6. public SharedPreferences getSharedPreferences(String name, int mode){  
  7.      //其所對應的SharedPreferencesImpl對象 ,該對象已一個HashMap集合保存了我們對該文件序列化結果  
  8.      SharedPreferencesImpl sp;    
  9.      File f = getSharedPrefsFile(name);  //該包下是否存在對應的文件,不存在就新建一個  
  10.      synchronized (sSharedPrefs) {       //是否已經讀取過該文件,是就直接返回該SharedPreferences對象  
  11.          sp = sSharedPrefs.get(f);  
  12.          if (sp != null && !sp.hasFileChanged()) {  
  13.              //Log.i(TAG, "Returning existing prefs " + name + ": " + sp);  
  14.              return sp;  
  15.          }  
  16.      }  
  17.      //以下為序列化該xml文件,同時將數據寫到map集合中       
  18.      Map map = null;  
  19.      if (f.exists() && f.canRead()) {  
  20.          try {  
  21.              str = new FileInputStream(f);  
  22.              map = XmlUtils.readMapXml(str);  
  23.              str.close();  
  24.          }   
  25.          ...  
  26.      }  
  27.        
  28.      synchronized (sSharedPrefs) {  
  29.          if (sp != null) {  
  30.              //Log.i(TAG, "Updating existing prefs " + name + " " + sp + ": " + map);  
  31.              sp.replace(map);   //更新數據集合  
  32.          } else {  
  33.              sp = sSharedPrefs.get(f);  
  34.              if (sp == null) {    
  35.                  //新建一個SharedPreferencesImpl對象,并且設置其相關屬性  
  36.                  sp = new SharedPreferencesImpl(f, mode, map);    
  37.                  sSharedPrefs.put(f, sp);  
  38.              }  
  39.          }  
  40.          return sp;  
  41.      }  
  42. }  

 

   2、 SharedPreferences 不過是個接口,它定義了一些操作xml文件的方法,其真正實現類為SharedPreferencesImpl ,該類是

    ContextIml的內部類,該類如下:

 

  1. //soga,這種形式我們在分析Context ContextIml時接觸過   
  2. //SharedPreferences只是一種接口,其真正實現類是SharedPreferencesImpl類  
  3. private static final class SharedPreferencesImpl implements SharedPreferences{  
  4.      private Map mMap;  //保存了該文件序列化結果后的操作, 鍵值對形式  
  5.        
  6.      //通過key值獲取對應的value值  
  7.      public String getString(String key, String defValue) {  
  8.          synchronized (this) {  
  9.              String v = (String)mMap.get(key);  
  10.              return v != null ? v : defValue;  
  11.          }  
  12.      }  
  13.      ...  
  14.      //獲得該SharedPreferencesImpl對象對應的Edito類,對數據進行操作  
  15.      public final class EditorImpl implements Editor {  
  16.          private final Map<String, Object> mModified = Maps.newHashMap(); //保存了對鍵值變化的集合  
  17.      }  
  18. }  

 



       基本上獲取SharedPreferences 對象就是這么來的,關于Context里的更多方法請大家參照源代碼認真學習吧。

 

 

posted on 2012-03-19 16:44 life02 閱讀(6356) 評論(0)  編輯 收藏 引用 所屬分類: Android開發
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            aa级大片欧美| 欧美女主播在线| 国产精品一区免费观看| 欧美在线播放| 麻豆精品精华液| 在线亚洲美日韩| 欧美在线关看| 日韩亚洲成人av在线| 亚洲男人的天堂在线aⅴ视频| 亚洲大黄网站| 亚洲一区二区成人| 亚洲精品国产精品乱码不99| 亚洲一区在线播放| 亚洲精品一区二区三区樱花| 亚洲欧美日韩国产另类专区| 亚洲精品欧洲精品| 久久av二区| 亚洲免费视频网站| 欧美大片在线观看| 久久成人人人人精品欧| 欧美日本亚洲| 欧美激情第三页| 国产综合av| 在线午夜精品| 99精品欧美一区二区蜜桃免费| 欧美一区二区三区啪啪| 亚洲一区二区免费视频| 欧美夫妇交换俱乐部在线观看| 久久久一区二区| 国产精品一区二区三区四区| 亚洲精品日韩在线观看| 亚洲福利视频专区| 久久精品官网| 久久不见久久见免费视频1| 欧美日韩精品免费在线观看视频| 美玉足脚交一区二区三区图片| 亚洲激情在线| 国产日韩欧美精品| 亚洲色诱最新| 一区二区三区免费网站| 欧美成人精精品一区二区频| 美女久久一区| 精品二区视频| 久久久久网址| 免费欧美电影| 一区二区亚洲欧洲国产日韩| 欧美在线高清视频| 久久久久久久久岛国免费| 国产麻豆视频精品| 亚洲欧美高清| 欧美中在线观看| 国产欧美一区二区精品婷婷| 亚洲资源在线观看| 欧美一区二区三区视频免费| 国产精品影视天天线| 亚洲一区精品电影| 亚洲一区激情| 国产精品亚洲аv天堂网| 亚洲在线第一页| 欧美有码视频| 国内久久精品| 免费成人av在线| 亚洲欧洲日本mm| 亚洲一级在线观看| 国产精品女同互慰在线看| 午夜日本精品| 欧美成人免费全部| 99国产精品久久久久久久| 欧美调教vk| 欧美一区二区福利在线| 免费看黄裸体一级大秀欧美| 亚洲精品乱码久久久久久蜜桃91 | 国产一区二区三区免费在线观看| 亚洲视频综合| 欧美日韩一视频区二区| 亚洲永久在线观看| 久久亚洲综合| 亚洲欧洲在线视频| 欧美三日本三级三级在线播放| 亚洲尤物在线| 欧美18av| 亚洲综合导航| 在线观看国产精品网站| 欧美日韩成人在线| 午夜在线视频一区二区区别| 你懂的视频欧美| 亚洲一区影院| 亚洲电影av在线| 欧美先锋影音| 久久亚洲免费| 亚洲中字在线| 亚洲国产精品久久| 欧美伊人久久久久久午夜久久久久| 黄色亚洲大片免费在线观看| 欧美伦理影院| 久久久久久久网站| 在线视频欧美日韩精品| 欧美本精品男人aⅴ天堂| 亚洲欧美成人精品| 91久久香蕉国产日韩欧美9色| 国产精品美女久久久久久2018| 狼人天天伊人久久| 亚洲欧美制服另类日韩| 亚洲激情六月丁香| 久久天天躁狠狠躁夜夜爽蜜月| 亚洲午夜久久久久久久久电影院| 91久久亚洲| 久久五月婷婷丁香社区| 久久综合给合久久狠狠色| 国产欧美69| 欧美另类在线播放| 国产乱码精品| 欧美jizzhd精品欧美巨大免费| 夜夜爽av福利精品导航| 国产一区导航| 欧美日韩国产天堂| 久久精品日产第一区二区三区| 91久久精品国产91久久| 久久久久九九视频| 午夜国产一区| 亚洲一区二区在线视频| 亚洲日本va午夜在线影院| 亚洲美女免费精品视频在线观看| 米奇777在线欧美播放| 欧美在线视频一区二区| 亚洲性夜色噜噜噜7777| 99精品国产在热久久下载| 亚洲欧洲一区二区三区久久| 在线不卡免费欧美| 激情久久中文字幕| 韩日精品视频一区| 国产亚洲一本大道中文在线| 国产精品一区免费观看| 国产精品一区二区你懂得 | 在线免费高清一区二区三区| 国产日韩精品在线播放| 国产精品午夜视频| 国产精品一区二区在线观看| 国产精品一二一区| 国产伦精品一区二区三区视频黑人| 国产精品高潮呻吟视频| 欧美亚洲不卡| 国产精品五月天| 国产一级揄自揄精品视频| 国产一区二区三区在线观看视频 | 日韩午夜激情av| 99国内精品久久| 亚洲视频一区在线观看| 亚洲一区国产| 欧美一区精品| 久久久噜噜噜| 欧美成人免费全部观看天天性色| 欧美成人高清| 欧美日韩成人| 国产精品亚洲欧美| 国产一区欧美| 亚洲精品久久久久中文字幕欢迎你| 亚洲精品日本| 亚洲专区一区| 久久久精品欧美丰满| 欧美高清视频www夜色资源网| 亚洲黄一区二区三区| 中日韩美女免费视频网址在线观看| 亚洲欧美成人综合| 久久天天躁狠狠躁夜夜av| 欧美精品三级| 国产伦精品一区二区三区在线观看 | 亚洲国产婷婷综合在线精品| 亚洲免费观看高清完整版在线观看熊 | 亚洲大片免费看| 日韩午夜av在线| 午夜欧美精品| 欧美国产一区二区在线观看 | 日韩网站在线| 亚洲欧美日韩在线不卡| 老司机一区二区| 国产精品国色综合久久| 在线成人黄色| 亚洲一区二区四区| 久久综合给合| 在线亚洲伦理| 老司机午夜精品| 国产精品嫩草影院一区二区| 亚洲第一页自拍| 午夜精品久久久久久99热软件| 免费人成网站在线观看欧美高清| 亚洲精品综合在线| 久久美女艺术照精彩视频福利播放| 欧美日韩一区二| 亚洲大片av| 欧美一区二区视频观看视频| 亚洲国产精品一区二区www| 亚洲永久免费av| 欧美精品一区二区三区在线播放 | 一本久道久久综合中文字幕| 久久久久久电影| 国产精品一区二区在线| 一本色道久久综合亚洲精品不卡| 鲁大师影院一区二区三区| 亚洲一区二区三区四区中文 |