Android NFC P2P学习1 - API层
API层入口为setNdefPushMessage,位于NfcAdapter类
public void setNdefPushMessage(NdefMessage message, Activity activity, Activity ... activities) { if (activity == null) { throw new NullPointerException("activity cannot be null"); } mNfcActivityManager.setNdefPushMessage(activity, message); for (Activity a : activities) { if (a == null) { throw new NullPointerException("activities cannot contain null"); } mNfcActivityManager.setNdefPushMessage(a, message); } }
NfcAdapter类中有个成员变量NfcActivityManager,该类内部使用一个WeakHashmap存放所有需要进行NFC P2P推送的Activity。Key为Activity本身,Value为NfcActivityState。NfcActivityState保存和NFC P2P相关的一些对象及Activity的状态。
由于NFC P2P推送只有在Activity为前景Activity的状态下会执行,所以NfcActivityState中会保存Activity的状态,另外还保存着待推送的NdefMessage、和NFC P2P推送相关的回调接口对象。
/** * NFC state associated with an {@link Activity} */ class NfcActivityState { boolean resumed = false; // is the activity resumed NdefMessage ndefMessage; NfcAdapter.CreateNdefMessageCallback ndefMessageCallback; NfcAdapter.OnNdefPushCompleteCallback onNdefPushCompleteCallback; @Override public String toString() { StringBuilder s = new StringBuilder("[").append(resumed).append(" "); s.append(ndefMessage).append(" ").append(ndefMessageCallback).append(" "); s.append(onNdefPushCompleteCallback).append("]"); return s.toString(); } }
下面来看NfcActivityManager中setNdefPushMessage做了什么?
public synchronized void setNdefPushMessage(Activity activity, NdefMessage message) { NfcActivityState state = getOrCreateState(activity, message != null); if (state == null || state.ndefMessage == message) { return; // nothing more to do; } state.ndefMessage = message; if (message == null) { maybeRemoveState(activity, state); } if (state.resumed) { updateNfcService(state); } }
1、判断这个要进行NFC P2P推送的Activity在不在Hashmap中,如若不存在,则创建
2、若传入的NdefMessage为null,则通过maybeRemoveState判断是否与该Activity的NFC P2P相关的两个回调接口是否也是null,如果3个对象都为null,那么意味着这个Activity不需要进行NFC P2P推送,那么便从Hashmap中删除掉它。(所以虽然名称叫做NfcActivityManager,但实际上这个管理器只管理那些与NFC P2P推送相关的Activity)
3、如果这个Activity的状态是resumed,那么通过进程间通信IPC,调用NfcService中的Stub对象:NfcAdapterService
下面来看一看Nfc Service层的具体代码:
@Override public void setForegroundNdefPush(NdefMessage msg, INdefPushCallback callback) { mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); mP2pLinkManager.setNdefToSend(msg, callback); }
这里我们细细研究步骤2,即maybeRemoveState(activity, state);代码如下:
/** * If the NfcActivityState is empty then remove it, and * detach it from the Activity. */ synchronized void maybeRemoveState(Activity activity, NfcActivityState state) { if (state.ndefMessage == null && state.ndefMessageCallback == null && state.onNdefPushCompleteCallback == null) { NfcFragment.remove(activity); mNfcState.remove(activity); } }
出现了一个新的类NfcFragment,该类继承自Fragment,相信Fragment大家还是比较熟悉的,这里的NfcFragment正式利用了Fragment与Activity生命周期相关的特性,代码如下:
public final class NfcFragment extends Fragment { static final String FRAGMENT_TAG = "android.nfc.NfcFragment"; // only used on UI thread static boolean sIsInitialized = false; static NfcActivityManager sNfcActivityManager; /** * Attach NfcFragment to an activity (if not already attached). */ public static void attach(Activity activity) { FragmentManager manager = activity.getFragmentManager(); if (manager.findFragmentByTag(FRAGMENT_TAG) == null) { manager.beginTransaction().add(new NfcFragment(), FRAGMENT_TAG).commit(); } } /** * Remove NfcFragment from activity. */ public static void remove(Activity activity) { FragmentManager manager = activity.getFragmentManager(); Fragment fragment = manager.findFragmentByTag(FRAGMENT_TAG); if (fragment != null) { // We allow state loss at this point, because the state is only // lost when activity is being paused *AND* subsequently destroyed. // In that case, the app will setup foreground dispatch again anyway. manager.beginTransaction().remove(fragment).commitAllowingStateLoss(); } } @Override public void onAttach(Activity activity) { super.onAttach(activity); if (!sIsInitialized) { sIsInitialized = true; NfcAdapter adapter = NfcAdapter.getDefaultAdapter( activity.getApplicationContext()); if (adapter != null) { sNfcActivityManager = adapter.mNfcActivityManager; } } } @Override public void onResume() { super.onResume(); if (sNfcActivityManager != null) { sNfcActivityManager.onResume(getActivity()); } } @Override public void onPause() { super.onPause(); if (sNfcActivityManager != null) { sNfcActivityManager.onPause(getActivity()); } } @Override public void onDestroy() { super.onDestroy(); if (sNfcActivityManager != null) { sNfcActivityManager.onDestroy(getActivity()); } }}
上述代码可以得出结论:
1、一个Activity可以系上多个Fragment,由Activity中的FragmentManager进行管理
2、在Activity的pause,resume等发生的时候,Fragment对象中对应的方法会被回调
3、回调方法中的实现均为调用NfcActivityManager处理对应的操作,我们来看一下NfcActivityManager.onResume(Activity activity)
/** * onResume hook from fragment attached to activity */ public synchronized void onResume(Activity activity) { NfcActivityState state = mNfcState.get(activity); if (DBG) Log.d(TAG, "onResume() for " + activity + " " + state); if (state != null) { state.resumed = true; updateNfcService(state); } }
我们可以看到,其实是利用了Fragment与Activity维系在一起的生命周期,来更新NfcActivityState中的Activity的状态域resumed。
好了,我们终于看到了P2pLinkManager这个对象了,下一节再来研究NFC服务端的P2P流程。
更多相关文章
- android判断网络连接状态-ConnectivityManager
- android —— 常用代码utils
- Android中打开扬声器关闭麦克风的代码实现
- Android Studio:在xml布局中不能自动补全代码
- 几行让android进入休眠的c代码
- android 开发中常用到的一些代码片段(一)
- 如何在eclipse中查看Android各版本源代码
- Android 一键清理内存,缓存,文件代码
- Android纯代码写布局