《Android NFC开发实战详解》——6.4节Android NFC P2P开发进阶-阿里云开发者社区

开发者社区> 异步社区> 正文

《Android NFC开发实战详解》——6.4节Android NFC P2P开发进阶

简介:
+关注继续查看

本节书摘来自异步社区《Android NFC开发实战详解》一书中的第6章,第6.4节Android NFC P2P开发进阶,作者 赵波,更多章节内容可以访问云栖社区“异步社区”公众号查看

6.4 Android NFC P2P开发进阶
Android NFC开发实战详解
本节将介绍Android API 16+中引入的针对NFC P2P功能开发的新功能——文件传输进行介绍。该功能包括setBeamPushUrisCallback和setBeamPushUris两个方法。通过本节的介绍,大家可以结合NFC和蓝牙或WiFi很轻松的实现Android设备之间大数据(如图片、音乐等)的传输。

6.4.1 Beam实现文件传输的方法
Android4.1(Jelly Bean,Android API 16)新增了一种基于NFC和蓝牙(或WiFi)实现Android设备之间大数据传递的新方法,其中包含setBeamPushUrisCallback( )和setBeamPushUris( )两个方法。该方法比传统的蓝牙传输少了显示配对的过程,在你的应用无需考虑更多的其他工作同时还能发挥蓝牙传输的优势。

1.setBeamPushUrisCallback( )方法的原型
public void setBeamPushUrisCallback (NfcAdapter.CreateBeamUrisCallback callback, Activity activity)

其中,callback为通过Android Beam发送一个或多个动态生成的Uri(s)的回调接口;activity为当前调用该方法的activity,即push Uri(s)的Activity。

使用setBeamPushUrisCallback()方法时,应注意以下几点:

(1)该方法可以在Activity中任何位置调用(onDestroy()之前)。因为Uri只有Activity在前台状态(resume()状态)下才可用,所以Android的官方建议在OnCreate()中调用该方法。同时,由于该方法并不阻塞线程,因此可以在UI主线程中使用。

(2)使用该方法时,如果callback为null,则调用该方法的Activity的Uri Push功能将会disable。

(3)当同时使用该方法和setNdefPushMessage(NdefMessage, Activity, Activity...) 或setNdefPush MessageCallback(NfcAdapter.CreateNdefMessageCallback, Activity, Activity...)方法时,该方法具有较高优先级。

(4)关于该方法的使用,官方提供的使用范例如下(关于更详细的使用方法,读者可以参考本节后面的具体实例)。

protected void onCreate(Bundle savedInstanceState)
{
 super.onCreate(savedInstanceState);
 NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
 if (nfcAdapter == null)
  return; // NFC not available on this device
 nfcAdapter.setBeamPushUrisCallback(callback, this);
}

(5)如果用户的手机不支持蓝牙或WiFi,那么该方法将失效,使用该方法时则不会有任何反应。

(6)使用该方法需要在AndroidManifest.xml中添加NFC权限。

(7)在Android API 16+以上的系统中使用。

2.setBeamPushUris ( )方法的原型
public void setBeamPushUris (Uri[] uris, Activity activity):其中,uris为用于Android Beam的一个或多个Uri(s);activity为当前调用该方法的activity,即push Uri(s)的Activity。

使用setBeamPushUris()方法时,应注意以下几点:

(1)提供的每一个Uri中的Uri Scheme必须包含“file”或“content”。

(2)该方法可以在Activity中任何位置调用(onDestroy()之前)。因为Uri只有Activity在前台状态(resume()状态)下才可用,所以Android的官方建议在OnCreate()中调用该方法。同时,由于该方法并不阻塞线程,所以可以在UI主线程中使用。

(3)使用该方法时,如果Uri为null,则调用该方法的Activity的Uri Push功能将会disable。

(4)当同时使用该方法和setNdefPushMessage(NdefMessage, Activity, Activity...)或setNdefPush MessageCallback(NfcAdapter.CreateNdefMessageCallback, Activity, Activity...)方法时,该方法具有较高优先级。

(5)关于该方法的使用,官方提供的使用范例如下(关于更详细的使用方法,读者可以参考本节后面的具体实例)。

protected void onCreate(Bundle savedInstanceState)
{
 super.onCreate(savedInstanceState);
 NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
 if (nfcAdapter == null)
  return; // NFC not available on this device
 nfcAdapter.setBeamPushUris(new Uri[]
 { uri1, uri2 }, this);
 }
}

(6)如果用户的手机不支持蓝牙或WiFi,那么该方法将失效,使用该方法时则不会有任何反应。

(7)如果希望动态的提供Uri(s),那么可以使用上述的setBeamPushUrisCallback()方法。

(8)使用该方法需要在AndroidManifest.xml中添加NFC权限。

(9)在Android API 16+以上的系统中使用。

3.setBeamPushUrisCallback( ) 和setBeamPushUris( ) 的区别和选择
setBeamPushUrisCallback( )提供的是一个回调接口。当使用这个回调接口时,用户每Beam一次,该回调函数执行一次。如果待分享的Uri是动态的,会随着activity中的用户环境变化而变化,就可以使用该回调方法;反之,当待分享的Uri是静态的,是不会改变的,就可以使用setBeam PushUris( )方法提前定义好它们。总之,setBeamPushUris( )方法是在初始化Beam的同时立即提供Uri对象值,而setBeamPushUrisCallback( )回调方法在初始化Beam时并无需提供Uri对象值,而是在建立Beam连接时提供Uri对象值。

6.4.2 Beam文件传输实例1:setBeamPushUris
在Beam文件传输实例1中,本书对setBeamPushUris ( )方法实现Android Beam传输Uri功能进行了实例描述。由于Android Beam实现文件传输的方法中接收端可以由操作系统完成的,无需在App中处理,因此该实例中仅包括Uri发送端。Uri的Push部分主要包括两个步骤,分别为:

(1)在Activity中创建文件Uri。

(2)在需要的地方调用setBeamPushUris。

具体参见实例代码中对应的注释,详细代码如下:

1. package skyseraph.nfc_demo.p2p.beam.app;   //声明包

2. import skyseraph.android.util.LogUtil;  //导入相关类
3. ……//该处省略了导入相关类的代码
4. public class BeamFileDemo1 extends Activity implements OnClickListener
5. {
6.  private static final String Tag_ASSIST = "[BeamFileDemo1]-";
7.  private Context mContext = null;
8.  private boolean flagNFC = false;
9.  private boolean flagVersion = false;
10.  private static int mRequestCode = 1001;
11.  // NFC相关
12.  private NfcAdapter mNfcAdapter = null;
13. 
14.  @Override
15.  protected void onCreate(Bundle savedInstanceState)
16.  {
17.   // TODO Auto-generated method stub
18.   super.onCreate(savedInstanceState);
19.   mContext = this;
20.   LogUtil.i(MyConstant.Tag, Tag_ASSIST + "into onCreate");
21.   flagNFC = checkNFCFunction();
22.   LogUtil.i(MyConstant.Tag, Tag_ASSIST + "flagNFC=" + flagNFC);
23.   if (flagNFC)
24.   {
25.    checkSystemVersion();
26.    LogUtil.i(MyConstant.Tag, Tag_ASSIST + "flagVersion=" + flagVersion);
27.    if(flagVersion)
28.    {
29.     // BNM步骤1: Create 文件Uri
30.     Intent i = new Intent(Intent.ACTION_GET_CONTENT);   
     //用户选择某种特殊数据并返回
31.     i.setType("image/*");   
     //查看类型,如果是其他类型,如视频则替换成 video/*,或 */*
32.     startActivityForResult(i, mRequestCode);
33.    }
34.   }
35.  }
36. 
37. 
38.  /*
39.   * (non-Javadoc)
40.   * 
41.   * @see android.app.Activity#onActivityResult(int, int,
42.   * android.content.Intent)
43.   */
44.  @Override
45.  protected void onActivityResult(int requestCode, int resultCode, Intent data)
46.  {
47.   // TODO Auto-generated method stub
48.   // super.onActivityResult(requestCode, resultCode, data);
49.   if (requestCode == mRequestCode && resultCode == RESULT_OK) 
50.   {
51.    Uri[] uriArray = new Uri[]
52.    { data.getData() };
53.    LogUtil.i(MyConstant.Tag, Tag_ASSIST + "uriArray=" + uriArray);
54.    
55.    // BNM步骤2:call setBeamPushUris anywhere your want
56.    mNfcAdapter.setBeamPushUris(uriArray, this);
57. 
58.    Button btn = new Button(this);
59.    btn.setText("Touch this to finish!");
60.    btn.setTextSize(30);
61.    btn.setOnClickListener(this);
62.    setContentView(btn);
63.   }
64.  }
65. 
66.  @Override
67.  public void onClick(View v)
68.  {
69.   finish();
70.  }
71. 
72.  /**
73.   * NFC Function Check By skyseraph 2013-2
74.   */
75.  private boolean checkNFCFunction()
76.  {
77.   // TODO Auto-generated method stub
78.   mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
79.   if (mNfcAdapter == null)
80.   {
81.    // mTextView.setText("NFC apdater is not available");
82.    Dialog dialog = null;
83.    CustomDialog.Builder customBuilder = new CustomDialog.Builder (mContext);
84.    customBuilder.setTitle(getString(R.string.inquire)).setMessage(getString(R.string.  
 nfc_notice2))
85.      .setIcon(R.drawable.dialog_icon2)
86.      .setNegativeButton(getString(R.string.no), new Dialog   
      Interface.OnClickListener()
87.      {
88.       public void onClick(DialogInterface dialog, int which)
89.       {
90.        dialog.dismiss();
91.        finish();
92.       }
93.      }).setPositiveButton(getString(R.string.yes), new Dialog   
      Interface.OnClickListener()
94.      {
95.       public void onClick(DialogInterface dialog, int which)
96.       {
97.        dialog.dismiss();
98.        finish();
99.       }
100.      });
101.    dialog = customBuilder.create();
102.    dialog.setCancelable(false);// back
103.    dialog.setCanceledOnTouchOutside(false);
104.    SetDialogWidth(dialog).show();
105.    return false;
106.   } else
107.   {
108.    if (!mNfcAdapter.isEnabled())
109.    {
110.     Dialog dialog = null;
111.     CustomDialog.Builder customBuilder = new CustomDialog.Builder   
      (mContext);
112.     customBuilder.setTitle(getString(R.string.inquire)).setMessage(getString(R.string.  
 nfc_notice3))
113.       .setIcon(R.drawable.dialog_icon2)
114.       .setNegativeButton(getString(R.string.no), new   
       DialogInterface.OnClickListener()
115.       {
116.         public void onClick(DialogInterface dialog, int which)  
117.        {
118.         dialog.dismiss();
119.         finish();
120.        }
121.       }).setPositiveButton(getString(R.string.yes), new   
       DialogInterface.OnClickListener()
122.       {  
123.         public void onClick(DialogInterface dialog, int which)
124.        {
125.         dialog.dismiss();
126.         Intent setnfc = new Intent(Settings.   
         ACTION_WIRELESS_SETTINGS);
127.         // Intent setnfc = new
128.         // Intent(Settings.ACTION_NFC_SETTINGS);
129.         startActivity(setnfc);
130.        }
131.       });
132.     dialog = customBuilder.create();
133.     dialog.setCancelable(false);// back
134.     dialog.setCanceledOnTouchOutside(false);
135.     SetDialogWidth(dialog).show();
136.     return false;
137.    } else if (!mNfcAdapter.isNdefPushEnabled())
138.    {
139.     Intent setnfc = new Intent(Settings.ACTION_NFCSHARING_SETTINGS);
140.     startActivity(setnfc);
141.     return false;
142.    } else
143.    {
144.     return true;
145.    }
146.   }
147.  }
148. 
149.  /**
150.   * @param dialog
151.   * @return
152.   */
153.  private Dialog SetDialogWidth(Dialog dialog)
154.  {
155.   DisplayMetrics dm = new DisplayMetrics();
156.   // 取得窗口属性
157.   getWindowManager().getDefaultDisplay().getMetrics(dm);
158.   // 窗口的宽度
159.   int screenWidth = dm.widthPixels;
160.   // 窗口高度
161.   int screenHeight = dm.heightPixels;
162.   WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
163.   if (screenWidth > screenHeight)
164.   {
165.    params.width = (int) (((float) screenHeight) * 0.875);
166. 
167.   } else
168.   {
169.    params.width = (int) (((float) screenWidth) * 0.875);
170.   }
171.   dialog.getWindow().setAttributes(params);
172. 
173.   return dialog;
174.  }
175.  
176.  /**
177.   * check System Version()
178.   */
179.  private void checkSystemVersion()
180.  {
181.   // TODO Auto-generated method stub
182.   // if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
183. 
184.   LogUtil.i(MyConstant.Tag, Tag_ASSIST + "Product Model=" + android.os.     Build.MODEL + ", "+ android.os.Build.VERSION.SDK + ", " + android.os.Build. 
185.   VERSION.RELEASE);
186.   String systemModel;
187.   String releaseVersion;
188.   String sdkVersion;
189.   systemModel = android.os.Build.MODEL;
190.   sdkVersion = android.os.Build.VERSION.SDK;
191.   releaseVersion = android.os.Build.VERSION.RELEASE;
192.   if (Integer.parseInt(sdkVersion) > 15)
193.   {
194.    flagVersion = true;
195.   } else
196.   {
197.    flagVersion = false;
198.    Toast.makeText(mContext, "Your android system version is low to API-16", Toast.LENGTH_SHORT).show();
199.   }
200.  }
201. }

第21行为实现NFC功能的检测。在使用Android Beam功能前,需要确保设备支持NFC功能、NFC功能可用,且Android Beam功能是enable。具体可通过isEnabled() 和 isNdefPushEnabled()函数实现,参考代码第72~147行checkNFCFunction()函数。
第25行为实现系统版本的检测,因为setBeamPushUris ( )方法是在Android API 16+中才提供,所以此处加入了系统版本检测的代码。具体参考代码第176~200行checkSystemVersion()函数,该函数中主要通过android.os.Build.VERSION.SDK检测Android系统SDK API以及通过android.os.Build.VERSION.RELEASE检测Android系统版本。
第20~32行为BNM步骤1阶段,即准备Uri数据。代码通过Intent.ACTIONGET CONTENT进行过滤选择需要生产Uri的文件类型,本例中采用的是图片。
第38~64行中为onActivityResult()的处理,即用户选择了某个图片文件后进入到该函数中(根据第32行调用的startActivityForResult(i, mRequestCode)),具体包含了BNM步骤2阶段部分(即调用setBeamPushUris ( )方法)和UI操控部分(设置Button,用户触控结束该Activity)。
在AndroidManifest.xml中声明Activity,并添加NFC权限,其代码如下:

1. <uses-permission android:name="android.permission.NFC" />

2. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
3. <uses-feature
 android: name="android.hardware.nfc" 
 android:required="true" />
4. <activity
5.             android:name="skyseraph.nfc_demo.p2p.beam.app.BeamFileDemo1"
6.             android:label="NFC_Demo_BeamFile-1" >
7.             <intent-filter>
8.                 <action android:name="android.intent.action.MAIN" />
9. 
10.                 <category android:name="android.intent.category.skyseraph_nfc_demo" />
11.             </intent-filter>
12.         </activity>

第1行为APP添加NFC权限。
第2行为添加APP读取外部存储器权限。注意,在Android API 17+中已不再强调需要这个权限,但未来的平台版本可能会对想要从外部存储器上读取文件的应用程序要求这个权限。因此,为了确保兼容性,在它变成必须的要求之前,申请这个权限。
第3行为添加只有存在NFC功能的设备才能使用你的应用。
Beam文件传输实例1的具体效果如图6-13所示,其中,图6-13(a)为初次启动界面,即提示用户选择待分享的图片,用户选择完后,显示图6-13(b)所示的界面,此时,用户触碰界面结束当前分享界面。


d2369c9d563d2fd7a250d8df1737c9246b77de59

6.4.3 Beam文件传输实例2:setBeamPushUrisCallback
在Beam文件传输实例2中,本书对setBeamPushUrisCallback ( )方法实现Android Beam传输Uri功能进行了实例描述。同实例1,由于Android Beam实现文件传输的方法中接收端可以由操作系统完成的,无需在App中处理,因此实例2中也仅包括Uri发送端。Uri的Push部分主要包括三个步骤,分别为:

(1)在Activity中实现CreateBeamUrisCallback接口;

(2)在需要的地方调用setBeamPushUrisCallback;

(3)回调函数中实现Beam Data。

具体参见实例代码中对应的注释,详细代码如下:

1. package skyseraph.nfc_demo.p2p.beam.app;   //声明包

2. import skyseraph.android.util.LogUtil;  //导入相关类
3. ……//该处省略了导入相关类的代码
4. public class BeamFileDemo2 extends Activity implements CreateBeamUrisCallback,   
 OnClickListener
5. { // BNM步骤1:在你的Activity中实现CreateBeamUrisCallback接口(implements)
6.  private static final String Tag_ASSIST = "[BeamFileDemo2]-";
7.  private Context mContext = null;
8.  private boolean flagNFC = false;
9.  private static int mRequestCode = 1001;
10.  private Intent mIntent;
11.  // NFC相关
12.  private NfcAdapter mNfcAdapter = null;
13. 
14.  @Override
15.  protected void onCreate(Bundle savedInstanceState)
16.  {
17.   // TODO Auto-generated method stub
18.   super.onCreate(savedInstanceState);
19.   mContext = this;
20.   LogUtil.i(MyConstant.Tag, Tag_ASSIST + "into onCreate");
21.   flagNFC = checkNFCFunction();
22.   LogUtil.i(MyConstant.Tag, Tag_ASSIST + "flagNFC=" + flagNFC);
23. 
24.   if (flagNFC)
25.   {
26.    Intent i = new Intent(Intent.ACTION_GET_CONTENT);   
    // 用户选择某种特殊数据并返回
27.    i.setType("image/*"); // 查看类型,如果是其他类型,如视频则替换成 video/*,或 */*
28.    startActivityForResult(i, mRequestCode);
29.   }
30.  }
31. 
32.  // BNM步骤3:回调函数中实现Beam Data。
33.  // 当发现有支持Beam的手机时,该回调接口会自动激活,你只需将你需要Beam的文件Uri准备好  
  // 并返回即可。
34.  // 本例中Uri为用户选择的图片为例。
35.  @Override
36.  public Uri[] createBeamUris(NfcEvent event)
37.  {
38.   // TODO Auto-generated method stub
39.   LogUtil.i(MyConstant.Tag, Tag_ASSIST + "into createBeamUris");
40.   Uri[] uriArray = new Uri[]
41.   { mIntent.getData() };
42.   LogUtil.i(MyConstant.Tag, Tag_ASSIST + "uriArray=" + uriArray);
43.   return uriArray;
44.  }
45. 
46.  /*
47.   * (non-Javadoc)
48.   * 
49.   * @see android.app.Activity#onActivityResult(int, int,
50.   * android.content.Intent)
51.   */
52.  @Override
53.  protected void onActivityResult(int requestCode, int resultCode, Intent data)
54.  {
55.   // TODO Auto-generated method stub
56.   // super.onActivityResult(requestCode, resultCode, data);
57.   if (requestCode == mRequestCode && resultCode == RESULT_OK)
58.   {
59.    mIntent = data;
60.    // BNM步骤2:call setBeamPushUrisCallback anywhere your want
61.    mNfcAdapter.setBeamPushUrisCallback(this, this);
62. 
63.    Button btn = new Button(this);
64.    btn.setText("Touch this to finish!");
65.    btn.setTextSize(30);
66.    btn.setOnClickListener(this);
67.    setContentView(btn);
68.   }
69.  }
70. 
71.  @Override
72.  public void onClick(View v)
73.  {
74.   finish();
75.  }
76. 
77.  /**
78.   * NFC Function Check By skyseraph 2013-2
79.   */
80.  private boolean checkNFCFunction()
81.  {
82.   // Beam文件传输实例1中的checkNFCFunction()函数,该处省略
83.  }
84. 
85.  /**
86.   * @param dialog
87.   * @return
88.   */
89.  private Dialog SetDialogWidth(Dialog dialog)
90.  {
91.   // Beam文件传输实例1中的SetDialogWidth ()函数,该处省略
92.  }
93. }

第4行为BNM步骤1阶段,即实现CreateBeamUrisCallback接口。实现该接口后,该Activity中需重载createBeamUris()函数。在该函数中返回需要Beam 的文件的Uri。
第21行为实现NFC功能的检测。在使用Android Beam功能前,需要确保设备支持NFC功能、NFC功能可用,且Android Beam功能是enable,具体通过isEnabled() 和 isNdefPushEnabled()函数实现,参考代码第77~83行checkNFCFunction()函数。
第26~28行为用户选择Uri数据,代码中通过Intent.ACTION_GET_CONTENT进行过滤选择需要生产Uri的文件类型,本例中采用的是图片。
第60~61行为BNM步骤2阶段,即调用setBeamPushUrisCallback(),调用该方法后Activity中会接收一个回调接口,一旦有发现其他设备的Beam数据,createBeamUris()就会自动调用。
第32~44行为BNM步骤3阶段,即回调接口createBeamUris(NfcEvent)中实现Beam Data,具体为将第26描述的用户选择的Uri数据获取并返回,Uri数组中的图片文件就会自动Beam to目标设备。
AndroidManifest.xml中声明Activity,并添加NFC权限,其代码如下:

1. <uses-permission android:name="android.permission.NFC" />

2. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
3. <uses-feature   
 android: name="android.hardware.nfc"   
 android:required="true" />
4. <activity
5.             android:name="skyseraph.nfc_demo.p2p.beam.app.BeamFileDemo2"
6.             android:label="NFC_Demo_BeamFile-2" >
7.             <intent-filter>
8.                 <action android:name="android.intent.action.MAIN" />
9. 
10.                 <category android:name="android.intent.category.skyseraph_nfc_demo" />
11.             </intent-filter>
12.         </activity>

第1行为APP添加NFC权限。
第2行为添加APP读取外部存储器权限。注意,虽然在Android 4.2.2 (API 17)中已不再强调需要这个权限,但未来的平台版本可能会对想要从外部存储器上读取文件的应用程序要求这个权限。因此,为了确保兼容性,在它变成必须的要求之前,申请这个权限。
第3行为添加只有存在NFC功能的设备才能使用应用。
Beam文件传输实例2的具体效果如图6-14所示。其中,图6-14(a)为初次启动界面,即提示用户选择待分享的图片。用户选择完后,显示图6-14(b)所示的界面。此时,用户触碰界面结束当前分享界面。


f40926aac0e608ea2936cb127b77134f6fa28e37

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Android官方开发文档Training系列课程中文版:连接无线设备之通过WIFI创建P2P连接
原文地址:http://android.xsoftlab.net/training/connect-devices-wirelessly/wifi-direct.html#permissions Wi-Fi peer-to-peer (P2P) APIs可以使程序与附近的设备进行直接通讯,Android的Wi-Fi P2P框架由Wi-Fi Direct™提供技术支持。
757 0
Android官方开发文档Training系列课程中文版:连接无线设备之通过P2P搜索网络服务
原文地址:http://android.xsoftlab.net/training/connect-devices-wirelessly/nsd-wifi-direct.html 本阶段的第一节课 Using Network Service Discovery 展示了如何搜索本地网络服务。
864 0
纯键盘开发实战(Mouseless Programming)
作为一个践行Mouseless Programming的开发者,来谈谈自己在日常工作中是如何做到「几乎」不用鼠标的。 在说具体的「技巧」之前,先聊一聊纯键盘开发的几个原则: 1. **动机**, 动机要单纯,纯键盘开发不是为了耍酷, 你的动机应该是提高「效率」:) 2. **键盘只是工具,思想才是关键**, 代码和问题先想清楚再下手,想清楚远比写的快重要! 3. **键盘不要经
1764 0
《仿人机器人原理与实战》一2.4 行为链实验进阶
本节书摘来华章计算机《仿人机器人原理与实战》一书中的第2章 ,第2.4节,作者布莱恩·伯杰伦(Bryan Bergeron) 托马斯B. 塔尔博特(Thomas B. Talbot) 王伟 魏洪兴 刘斐 译, 更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1462 0
《React Native移动开发实战》一一1.6 小 结
本节书摘来自华章出版社《React Native移动开发实战》一 书中的第1章,第1.6节,作者:袁林 著 ,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
826 0
Apache Flink 进阶(八):详解 Metrics 原理与实战
Flink 提供的 Metrics 可以在 Flink 内部收集一些指标,通过这些指标让开发人员更好地理解作业或集群的状态。由于集群运行后很难发现内部的实际状况,跑得慢或快,是否异常等,开发人员无法实时查看所有的 Task 日志,比如作业很大或者有很多作业的情况下,该如何处理?此时 Metrics 可以很好的帮助开发人员了解作业的当前状况。
4631 0
+关注
异步社区
异步社区(www.epubit.com)是人民邮电出版社旗下IT专业图书旗舰社区,也是国内领先的IT专业图书社区,致力于优质学习内容的出版和分享,实现了纸书电子书的同步上架,于2015年8月上线运营。公众号【异步图书】,每日赠送异步新书。
12049
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《Nacos架构&原理》
立即下载
《看见新力量:二》电子书
立即下载
云上自动化运维(CloudOps)白皮书
立即下载