网络数据是应用的主要数据来源,对于一个应用来说连接到互联网是最基本的需求,也是最常用的功能。但是网络总是存在各种各样的稳定性问题,而如何避开这些问题,实现一个稳定的,交互流畅的应用是对开发人员的基本要求。以下总结了一些网络操作的基楚知识和注意点。
1.使用网络的权限:
使用网络请求必须要添加的两个请求
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
2.检查网络状况
在我们的 app 尝试连接网络之前,应通过函数 getActiveNetworkInfo() 和 isConnected() 检测当前网络是否可用。
public void myClickHandler(View view) {
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
// fetch data 可用
} else {
// display error ,不可用
}
}
注意:网络操作会遇到不可预期的延迟。为了避免造成不好的用户体验,总是在 UI 线程之外单独的线程中执行网络操作。
- ConnectivityManager:它会回答关于网络连接的查询结果,并在网络连接改变时通知应用程序。
- NetworkInfo:描述一个给定类型(就本节而言是移动网络或 Wi-Fi)的网络接口状态。
2.检查设备的网络连接
以下代码检查了 Wi-Fi 与移动网络的网络连接。它检查了这些网络接口是否可用(也就是说网络是通的)及是否已连接(也就是说网络连接存在,并且可以建立 socket 来传输数据):
private static final String DEBUG_TAG = "NetworkStatusExample";
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
boolean isWifiConn = networkInfo.isConnected();
networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
boolean isMobileConn = networkInfo.isConnected();
Log.d(DEBUG_TAG, "Wifi connected: " + isWifiConn);
Log.d(DEBUG_TAG, "Mobile connected: " + isMobileConn);
一个更简洁的检查网络是否可用的示例如下。getActiveNetworkInfo() 方法返回一个 NetworkInfo 实例,它表示可以找到的第一个已连接的网络接口,如果返回 null,则表示没有已连接的网络接口(意味着网络连接不可用):
public boolean isOnline() {
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
return (networkInfo != null && networkInfo.isConnected());
}
3.检测网络连接变化
NetworkReceiver。 当设备网络连接改变时,NetworkReceiver 会监听到 CONNECTIVITY_ACTION,这时需要判断当前网络连接类型并相应的设置好 wifiConnected 与 mobileConnected。
下面是 NetworkReceiver 的代码:
public class NetworkReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager conn = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = conn.getActiveNetworkInfo();
// Checks the user prefs and the network connection. Based on the result, decides whether
// to refresh the display or keep the current display.
// If the userpref is Wi-Fi only, checks to see if the device has a Wi-Fi connection.
if (WIFI.equals(sPref) && networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
// If device has its Wi-Fi connection, sets refreshDisplay
// to true. This causes the display to be refreshed when the user
// returns to the app.
refreshDisplay = true;
Toast.makeText(context, R.string.wifi_connected, Toast.LENGTH_SHORT).show();
// If the setting is ANY network and there is a network connection
// (which by process of elimination would be mobile), sets refreshDisplay to true.
} else if (ANY.equals(sPref) && networkInfo != null) {
refreshDisplay = true;
// Otherwise, the app can't download content--either because there is no network
// connection (mobile or Wi-Fi), or because the pref setting is WIFI, and there
// is no Wi-Fi connection.
// Sets refreshDisplay to false.
} else {
refreshDisplay = false;
Toast.makeText(context, R.string.lost_connection, Toast.LENGTH_SHORT).show();
}
}