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流程。

更多相关文章

  1. android判断网络连接状态-ConnectivityManager
  2. android —— 常用代码utils
  3. Android中打开扬声器关闭麦克风的代码实现
  4. Android Studio:在xml布局中不能自动补全代码
  5. 几行让android进入休眠的c代码
  6. android 开发中常用到的一些代码片段(一)
  7. 如何在eclipse中查看Android各版本源代码
  8. Android 一键清理内存,缓存,文件代码
  9. Android纯代码写布局

随机推荐

  1. 从游戏AI到自动驾驶,一文看懂强化学习的概
  2. Python代码实操:详解数据清洗
  3. AER强调计量方法的重要性, 经济学因果分
  4. 迎战SDR、EW应用: Curtiss-Wright推出专用
  5. 基于Apache Flink的爱奇艺实时计算平台建
  6. Xilinx参与25G和50G互连性测试大会
  7. 中介效应最新进展: 中介效应中的工具变量
  8. 以太网的下一阶段:400GE网络
  9. 微博基于Flink的机器学习实践
  10. 广义三阶段空间最小二乘估计法(GS3SLS)是