• <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>

            life02

              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
              197 隨筆 :: 3 文章 :: 37 評(píng)論 :: 0 Trackbacks

            轉(zhuǎn)載必須注明出處 :http://blog.csdn.net/qinjuning

             

             

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

             

             

             

             

                    大家好,  今天給大家介紹下我們?cè)趹?yīng)用開發(fā)中最熟悉而陌生的朋友-----Context類 ,說它熟悉,是應(yīng)為我們?cè)陂_發(fā)中

               時(shí)刻的在與它打交道,例如:Service、BroadcastReceiver、Activity等都會(huì)利用到Context的相關(guān)方法 ; 說它陌生,完全是

               因?yàn)槲覀冋嬲牟欢瓹ontext的原理、類結(jié)構(gòu)關(guān)系。一個(gè)簡(jiǎn)單的問題是,一個(gè)應(yīng)用程序App中存在多少個(gè)Context實(shí)例對(duì)象呢?

               一個(gè)、兩個(gè)? 在此先賣個(gè)關(guān)子吧。讀了本文,相信您會(huì)豁然開朗的 。

             

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

                     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

             

                從上可知一下三點(diǎn),即:

                    1、它描述的是一個(gè)應(yīng)用程序環(huán)境的信息,即上下文。

                    2、該類是一個(gè)抽象(abstract class)類,Android提供了該抽象類的具體實(shí)現(xiàn)類(后面我們會(huì)講到是ContextIml類)。

                    3、通過它我們可以獲取應(yīng)用程序的資源和類,也包括一些應(yīng)用級(jí)別操作,例如:?jiǎn)?dòng)一個(gè)Activity,發(fā)送廣播,接受Intent

                  信息 等。。

             

             

               于是,我們可以利用該Context對(duì)象去構(gòu)建應(yīng)用級(jí)別操作(application-level operations) 。

             

             一、Context相關(guān)類的繼承關(guān)系

             

                                     

             

              相關(guān)類介紹:

             

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

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

                  源代碼(部分)如下:   

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

             

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

                      說明:該Context類的實(shí)現(xiàn)類為ContextIml,該類實(shí)現(xiàn)了Context類的功能。請(qǐng)注意,該函數(shù)的大部分功能都是直接調(diào)用

                  其屬性mPackageInfo去完成,這點(diǎn)我們后面會(huì)講到。    

                     源代碼(部分)如下:

            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程序公用一個(gè)mPackageInfo對(duì)象  
            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.         //開始啟動(dòng)一個(gè)Activity  
            23.         mMainThread.getInstrumentation().execStartActivity(  
            24.             getOuterContext(), mMainThread.getApplicationThread(), null, null, intent, -1);  
            25.     }  
            26. }  

             


             

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

                    說明: 正如其名稱一樣,該類只是對(duì)Context類的一種包裝,該類的構(gòu)造函數(shù)包含了一個(gè)真正的Context引用,即ContextIml

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

            1. public class ContextWrapper extends Context {  
            2.     Context mBase;  //該屬性指向一個(gè)ContextIml實(shí)例,一般在創(chuàng)建Application、Service、Activity時(shí)賦值  
            3.       
            4.     //創(chuàng)建Application、Service、Activity,會(huì)調(diào)用該方法給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);  //調(diào)用mBase實(shí)例方法  
            14.     }  
            15. }  

             


             

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

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

               所以Service直接繼承于ContextWrapper類。

                  源代碼(部分)如下:

            1. public class ContextThemeWrapper extends ContextWrapper {  
            2.      //該屬性指向一個(gè)ContextIml實(shí)例,一般在創(chuàng)建Application、Service、Activity時(shí)賦值  
            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類本質(zhì)上都是Context子類, 更多信息大家可以自行參考源代碼進(jìn)行理解。

             

             

            二、 什么時(shí)候創(chuàng)建Context實(shí)例 

             

                  熟悉了Context的繼承關(guān)系后,我們接下來分析應(yīng)用程序在什么情況需要?jiǎng)?chuàng)建Context對(duì)象的?應(yīng)用程序創(chuàng)建Context實(shí)例的

             情況有如下幾種情況:

                  1、創(chuàng)建Application 對(duì)象時(shí), 而且整個(gè)App共一個(gè)Application對(duì)象

                  2、創(chuàng)建Service對(duì)象時(shí)

                  3、創(chuàng)建Activity對(duì)象時(shí)

             

                因此應(yīng)用程序App共有的Context數(shù)目公式為:

             

                                 總Context實(shí)例個(gè)數(shù) = Service個(gè)數(shù) + Activity個(gè)數(shù) + 1(Application對(duì)應(yīng)的Context實(shí)例)

             

              具體創(chuàng)建Context的時(shí)機(jī)

             

                 1、創(chuàng)建Application對(duì)象的時(shí)機(jī)

             

                   每個(gè)應(yīng)用程序在第一次啟動(dòng)時(shí),都會(huì)首先創(chuàng)建Application對(duì)象。如果對(duì)應(yīng)用程序啟動(dòng)一個(gè)Activity(startActivity)流程比較

            清楚的話,創(chuàng)建Application的時(shí)機(jī)在創(chuàng)建handleBindApplication()方法中,該函數(shù)位于 ActivityThread.java類中 ,如下:

            1. //創(chuàng)建Application時(shí)同時(shí)創(chuàng)建的ContextIml實(shí)例  
            2. private final void handleBindApplication(AppBindData data){  
            3.     ...  
            4.     ///創(chuàng)建Application對(duì)象  
            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();    //創(chuàng)建一個(gè)ContextImpl對(duì)象實(shí)例  
            14.         appContext.init(this, null, mActivityThread);  //初始化該ContextIml實(shí)例的相關(guān)屬性  
            15.         ///新建一個(gè)Application對(duì)象   
            16.         app = mActivityThread.mInstrumentation.newApplication(  
            17.                 cl, appClass, appContext);  
            18.        appContext.setOuterContext(app);  //將該Application實(shí)例傳遞給該ContextImpl實(shí)例           
            19.     }   
            20.     ...  
            21. }  

             

             

                2、創(chuàng)建Activity對(duì)象的時(shí)機(jī)

             

                   通過startActivity()或startActivityForResult()請(qǐng)求啟動(dòng)一個(gè)Activity時(shí),如果系統(tǒng)檢測(cè)需要新建一個(gè)Activity對(duì)象時(shí),就會(huì)

              回調(diào)handleLaunchActivity()方法,該方法繼而調(diào)用performLaunchActivity()方法,去創(chuàng)建一個(gè)Activity實(shí)例,并且回調(diào)

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

            1. //創(chuàng)建一個(gè)Activity實(shí)例時(shí)同時(shí)創(chuàng)建ContextIml實(shí)例  
            2. private final void handleLaunchActivity(ActivityRecord r, Intent customIntent) {  
            3.     ...  
            4.     Activity a = performLaunchActivity(r, customIntent);  //啟動(dòng)一個(gè)Activity  
            5. }  
            6. private final Activity performLaunchActivity(ActivityRecord r, Intent customIntent) {  
            7.     ...  
            8.     Activity activity = null;  
            9.     try {  
            10.         //創(chuàng)建一個(gè)Activity對(duì)象實(shí)例  
            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();      //創(chuàng)建一個(gè)Activity實(shí)例  
            16.         appContext.init(r.packageInfo, r.token, this);   //初始化該ContextIml實(shí)例的相關(guān)屬性  
            17.         appContext.setOuterContext(activity);            //將該Activity信息傳遞給該ContextImpl實(shí)例  
            18.         ...  
            19.     }  
            20.     ...      
            21. }  

             

             

               3、創(chuàng)建Service對(duì)象的時(shí)機(jī)

             

                   通過startService或者bindService時(shí),如果系統(tǒng)檢測(cè)到需要新創(chuàng)建一個(gè)Service實(shí)例,就會(huì)回調(diào)handleCreateService()方法,

             完成相關(guān)數(shù)據(jù)操作。handleCreateService()函數(shù)位于 ActivityThread.java類,如下:

            1. //創(chuàng)建一個(gè)Service實(shí)例時(shí)同時(shí)創(chuàng)建ContextIml實(shí)例  
            2. private final void handleCreateService(CreateServiceData data){  
            3.     ...  
            4.     //創(chuàng)建一個(gè)Service實(shí)例  
            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(); //創(chuàng)建一個(gè)ContextImpl對(duì)象實(shí)例  
            13.     context.init(packageInfo, null, this);   //初始化該ContextIml實(shí)例的相關(guān)屬性  
            14.     //獲得我們之前創(chuàng)建的Application對(duì)象信息  
            15.     Application app = packageInfo.makeApplication(false, mInstrumentation);  
            16.     //將該Service信息傳遞給該ContextImpl實(shí)例  
            17.     context.setOuterContext(service);  
            18.     ...  
            19. }  


             

                另外,需要強(qiáng)調(diào)一點(diǎn)的是,通過對(duì)ContextImp的分析可知,其方法的大多數(shù)操作都是直接調(diào)用其屬性mPackageInfo(該屬性類

            型為PackageInfo)的相關(guān)方法而來。這說明ContextImp是一種輕量級(jí)類,而PackageInfo才是真正重量級(jí)的類。而一個(gè)App里的

            有ContextIml實(shí)例,都對(duì)應(yīng)同一個(gè)packageInfo對(duì)象。

                        

             

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

            法就是通過調(diào)用getSharedPreferences()方法去根據(jù)相關(guān)信息獲取SharedPreferences對(duì)象。具體流程如下:

             

                1 、調(diào)用  getSharedPreferences()獲取對(duì)應(yīng)的的文件,該函數(shù)實(shí)現(xiàn)功能如下:

             

            1. //Context類靜態(tài)數(shù)據(jù)集合,以鍵值對(duì)保存了所有讀取該xml文件后所形成的數(shù)據(jù)集合  
            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.      //其所對(duì)應(yīng)的SharedPreferencesImpl對(duì)象 ,該對(duì)象已一個(gè)HashMap集合保存了我們對(duì)該文件序列化結(jié)果  
            8.      SharedPreferencesImpl sp;    
            9.      File f = getSharedPrefsFile(name);  //該包下是否存在對(duì)應(yīng)的文件,不存在就新建一個(gè)  
            10.      synchronized (sSharedPrefs) {       //是否已經(jīng)讀取過該文件,是就直接返回該SharedPreferences對(duì)象  
            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文件,同時(shí)將數(shù)據(jù)寫到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);   //更新數(shù)據(jù)集合  
            32.          } else {  
            33.              sp = sSharedPrefs.get(f);  
            34.              if (sp == null) {    
            35.                  //新建一個(gè)SharedPreferencesImpl對(duì)象,并且設(shè)置其相關(guān)屬性  
            36.                  sp = new SharedPreferencesImpl(f, mode, map);    
            37.                  sSharedPrefs.put(f, sp);  
            38.              }  
            39.          }  
            40.          return sp;  
            41.      }  
            42. }  

             

               2、 SharedPreferences 不過是個(gè)接口,它定義了一些操作xml文件的方法,其真正實(shí)現(xiàn)類為SharedPreferencesImpl ,該類是

                ContextIml的內(nèi)部類,該類如下:

             

            1. //soga,這種形式我們?cè)诜治鯟ontext ContextIml時(shí)接觸過   
            2. //SharedPreferences只是一種接口,其真正實(shí)現(xiàn)類是SharedPreferencesImpl類  
            3. private static final class SharedPreferencesImpl implements SharedPreferences{  
            4.      private Map mMap;  //保存了該文件序列化結(jié)果后的操作, 鍵值對(duì)形式  
            5.        
            6.      //通過key值獲取對(duì)應(yīng)的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對(duì)象對(duì)應(yīng)的Edito類,對(duì)數(shù)據(jù)進(jìn)行操作  
            15.      public final class EditorImpl implements Editor {  
            16.          private final Map<String, Object> mModified = Maps.newHashMap(); //保存了對(duì)鍵值變化的集合  
            17.      }  
            18. }  

             



                   基本上獲取SharedPreferences 對(duì)象就是這么來的,關(guān)于Context里的更多方法請(qǐng)大家參照源代碼認(rèn)真學(xué)習(xí)吧。

             

             

            posted on 2012-03-19 16:44 life02 閱讀(6335) 評(píng)論(0)  編輯 收藏 引用 所屬分類: Android開發(fā)
            久久久久四虎国产精品| 久久夜色精品国产噜噜亚洲AV| 韩国无遮挡三级久久| 2021久久精品国产99国产精品| 亚洲成人精品久久| 一级做a爰片久久毛片免费陪| 久久99国产综合精品女同| 一级做a爰片久久毛片免费陪| 99精品伊人久久久大香线蕉| 国产精品熟女福利久久AV| 亚洲精品第一综合99久久| 久久天天躁狠狠躁夜夜网站 | 国产aⅴ激情无码久久| 久久精品国产亚洲AV香蕉| 久久久久国色AV免费观看| 亚洲午夜久久久久久久久久| 香蕉久久一区二区不卡无毒影院| 久久精品aⅴ无码中文字字幕不卡| 久久久av波多野一区二区| 亚洲人AV永久一区二区三区久久| 99久久99这里只有免费费精品| 香港aa三级久久三级老师2021国产三级精品三级在 | 久久播电影网| 国产欧美久久久精品| 久久精品国产久精国产一老狼| 国产精品免费久久久久久久久| 午夜精品久久久久久99热| 武侠古典久久婷婷狼人伊人| 99久久精品免费国产大片| 国产成人精品久久一区二区三区| 久久综合亚洲色HEZYO社区| 精品国产婷婷久久久| 99久久精品免费国产大片| 伊人色综合久久| 亚洲国产精品人久久| 久久久精品免费国产四虎| 91久久精品91久久性色| 久久精品欧美日韩精品| 91精品国产乱码久久久久久 | 欧美日韩精品久久久免费观看| 久久久久无码国产精品不卡|