iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 16
0
  • Guide :
    • 介紹
    • Service
    • Adapter
    • Handover
    • Kernel

Adapter

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

https://ithelp.ithome.com.tw/upload/images/20191001/20120515oYB21nKw0s.jpg

這時候步驟 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 流程作分析。


Reference :


上一篇
[Day-15] Android Pie NFC (2) Service
下一篇
[Day-17] Android Pie NFC (4) Handover (1)
系列文
Android Pie 底層開發學習心得30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言