再來回憶一下上次附的時序圖:

這時候步驟 1 ~ 5 已經走完了,
來看一下第二部份的 NfcAdapter 如何被初始化和使用。
起初是由 SystemServiceRegistry 來維護註冊進去系統的所有服務,
其中就包含了第二條線的 NfcManager,
透過 getNfcAdapter() 而在 NfcAdapter 中通過服務名稱 ”nfc”,
間接調用到 NfcAdapterService。
frameworks/base/core/java/android/app/SystemServiceRegistry.java
 171 final class SystemServiceRegistry { 
 172     private static final String TAG = "SystemServiceRegistry";
... ...
**//這裡註冊了很多服務,我們可以看到其中一行就是我們要找的NfcManager**
 326         **registerService**(Context.NFC_SERVICE, **NfcManager**.class,
 327                 new CachedServiceFetcher<NfcManager>() {   
 328             @Override
 329             public NfcManager createService(ContextImpl ctx) {
 330                 return new NfcManager(ctx);
 331             }});
... ...
frameworks/base/core/java/android/nfc/NfcManager.java
 40 @SystemService(Context.NFC_SERVICE)
 41 public final class NfcManager {
 42     private final NfcAdapter mAdapter;
 43                
 44     /**        
 45      * @hide   
 46      */        
 47     public NfcManager(Context context) {
 48         **NfcAdapter adapter**;
 49         context = context.getApplicationContext();
 50         if (context == null) {
 51             throw new IllegalArgumentException(
 52                     "context not associated with any application (using a mock context?)");
 53         }      
 54         try {
**//調用NfcAdapter中的getNfcAdapter方法類獲取NfcAdapter**
 55             **adapter** = **NfcAdapter.getNfcAdapter**(context);
 56         } catch (UnsupportedOperationException e) {
 57             adapter = null;
 58         }      
 59         mAdapter = adapter;
 60     }          
 61                
... ...
我們可以看到上面的 NfcManager 非常非常短,
最後 NfcAdapter 會呼叫自己的 getNfcAdapter() 函式來塞給自己,
這裡很像繞口令,但不得不說能想到這方法蠻聰明的。
其中 getNfcAdapter() 為靜態方法 (Static Method),
可以直接通過類名 (Class Name) 進行操作:
frameworks/base/core/java/android/nfc/NfcAdapter.java
 488     /**          
 489      * Returns the NfcAdapter for application context,
 490      * or throws if NFC is not available.
 491      * @hide     
 492      */          
 493     public static synchronized NfcAdapter getNfcAdapter(Context context) {
//**判斷是否已經進行了初始化,如果沒有就獲取對應的狀態和服務**
 494         if (!sIsInitialized) {
//**判断是否支持NFC功能**
 495             sHasNfcFeature = hasNfcFeature();
//**是否支持NFC模擬卡的功能**
 496             boolean hasHceFeature = hasNfcHceFeature(); 
 497             /* is this device meant to have NFC */ 
//**如果不支持NFC功能就會拋出異常**     
 498             if (!sHasNfcFeature && !hasHceFeature) {    
 499                 Log.v(TAG, "this device does not have NFC support");
 500                 throw new UnsupportedOperationException();   
 501             }
//**獲取NFC服務,在下面的函數實例中可以看到通過服務名稱'nfc'來獲取**
 502             **sService = getServiceInterface**();           
 503             if (sService == null) {
 504                 Log.e(TAG, "could not retrieve NFC service");
 505                 throw new UnsupportedOperationException();   
 506             }
... ...
這裡看到 ServiceManager 透過 getService() 來得到名為 "nfc" 的服務:
frameworks/base/core/java/android/nfc/NfcAdapter.java
 546     /** get handle to NFC service interface */
 547     private static INfcAdapter getServiceInterface() {
 548         /* get a handle to NFC service */
//**通過名稱來獲取NfcService**
 549         IBinder b = **ServiceManager.getService("nfc");**
 550         if (b == null) {
 551             return null;
 552         }        
 553         return INfcAdapter.Stub.asInterface(b);
 554     }
這裡如果得到服務的話就呼叫 getNfcTagInterface():
frameworks/base/core/java/android/nfc/NfcAdapter.java
 493     public static synchronized NfcAdapter getNfcAdapter(Context context) {
 494         if (!sIsInitialized) {
... ...
 507             if (sHasNfcFeature) {      
 508                 try {
 509                     sTagService = **sService.getNfcTagInterface**(); 
 510                 } catch (RemoteException e) {           
 511                     Log.e(TAG, "could not retrieve NFC Tag service");
 512                     throw new UnsupportedOperationException();   
 513                 }
 514             }
... ...
**//這裡最後new一個NfcAdapter物件回傳**
 540             adapter = new NfcAdapter(context);
 541             sNfcAdapters.put(context, adapter);
 542         }       
 543         return adapter;
 544     }
下一篇我們會先跳到 Handover 的番外篇部份探討一下,
後續會再分別以設定中開啟 NFC 和感應 NFC 流程作分析。