再來回憶一下上次附的時序圖:
這時候步驟 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 流程作分析。