Connecting to the Network
This lesson shows you how to implement a simple application that connects to the network. It explains some of the best practices you should follow in creating even the simplest network-connected app.
本篇文档向您展示了如何实现一个可以连接到网络的应用。文章也给出了一些你在开发应用时应该注意的事项。
Note that to perform the network operations described in this lesson, your application manifest must include the following permissions:
记住,要想让你的应用执行一些与网络相关的操作,在你的manifest文件中添加以下的权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Choose an HTTP Client
Most network-connected Android apps use HTTP to send and receive data. Android includes two HTTP clients: HttpURLConnection
and Apache HttpClient
. Both support HTTPS, streaming uploads and downloads, configurable timeouts, IPv6, and connection pooling. We recommend using HttpURLConnection
for applications targeted at Gingerbread and higher. For more discussion of this topic, see the blog post Android's HTTP Clients.
大多数的安卓网络应用都是使用http协议来收发数据的。安卓包括两个http客户端类,一个是HttpUrlConnection,一个是阿帕奇的HttpClient。这两者都支持https协议,流数据的上传和下载,配置连接时长,IPV6,以及连接池技术。我们建议,在Gingerbread或者更高的版本中,使用HttpUrlConnection类。
Check the Network Connection
Before your app attempts to connect to the network, it should check to see whether a network connection is available using getActiveNetworkInfo()
and isConnected()
. Remember, the device may be out of range of a network, or the user may have disabled both Wi-Fi and mobile data access. For more discussion of this topic, see the lesson Managing Network Usage.
在你的应用连接网络之前,先使用getActiveNetworkInfo
方法和isConnected
()检测下网络连接是否可用。记住,用户随时会走出网络的范围,或者是用户会关掉wi-fi什么的。
其中,isConnected(),
Indicates whether network connectivity exists and it is possible to establish connections and pass data.
Always call this before attempting to perform data transactions.
判断是否有是否与网络建立连接。
Returns details about the currently active data network. When connected, this network is the default route for outgoing connections. You should always check isConnected()
before initiating network traffic. This may return null
when no networks are available.
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
}
...
}
Perform Network Operations on a Separate Thread
Network operations can involve unpredictable delays. To prevent this from causing a poor user experience, always perform network operations on a separate thread from the UI. The AsyncTask
class provides one of the simplest ways to fire off a new task from the UI thread. For more discussion of this topic, see the blog postMultithreading For Performance.
与网络相关的操作难免会有时延的问题,时延也是不可预见的。为了避免时延引起的糟糕的用户体验,将任何与网络相关的操作放在单独的线程中。AsyncTask类就提供了一个不错的方法,可以让一个与网络相关的操作不在主线程中运行。
In the following snippet, the myClickHandler()
method invokes new DownloadWebpageTask().execute(stringUrl)
. The DownloadWebpageTask
class is a subclass ofAsyncTask
. DownloadWebpageTask
implements the following AsyncTask
methods:
在下面的实例中,myClickHandler
方法会调用new DownloadWebpageTask().execute(stringUrl)
.其中,DownloadWebpageTask
类是AsyncTask类的一个子类,当然了,它就要实现AsyncTask类的方法:没有直接用AsyncTask类,而是使用它的子类。
doInBackground()
executes the methoddownloadUrl()
. It passes the web page URL as a parameter. The methoddownloadUrl()
fetches and processes the web page content. When it finishes, it passes back a result string.
实现的第一个方法是doInBackground。这个方法会执行子类DownloadWebpageTask
的downloadUrl
方法。也就是将下载操作放在doInBackground方法中实现。downloadUrl
方法的参数是一个要下载的网页地址。downloadUrl
下载该网页,并且处理网页内容。当处理网页操作结束后,downloadUrl
方法会返回一个字符串。
onPostExecute()
takes the returned string and displays it in the UI.
第二个要实现的方法是onPostExecute。这个方法会自动接收downloadUrl
方法返回的处理结果字符串,也就是接收doInBackGround方法返回的字符串。并且将这个字符串显示在界面上。
public class HttpExampleActivity extends Activity {
private static final String DEBUG_TAG = "HttpExample";
private EditText urlText;
private TextView textView; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
urlText = (EditText) findViewById(R.id.myUrl);
textView = (TextView) findViewById(R.id.myText);
} // When user clicks button, calls AsyncTask.
// Before attempting to fetch the URL, makes sure that there is a network connection.
public void myClickHandler(View view) {
// Gets the URL from the UI's text field.
String stringUrl = urlText.getText().toString();
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
new DownloadWebpageText().execute(stringUrl);
} else {
textView.setText("No network connection available.");
}
} // Uses AsyncTask to create a task away from the main UI thread. This task takes a
// URL string and uses it to create an HttpUrlConnection. Once the connection
// has been established, the AsyncTask downloads the contents of the webpage as
// an InputStream. Finally, the InputStream is converted into a string, which is
// displayed in the UI by the AsyncTask's onPostExecute method.
private class DownloadWebpageText extends AsyncTask {
@Override
protected String doInBackground(String... urls) { // params comes from the execute() call: params[0] is the url.
try {
return downloadUrl(urls[0]);
} catch (IOException e) {
return "Unable to retrieve web page. URL may be invalid.";
}
}
// onPostExecute displays the results of the AsyncTask.
@Override
protected void onPostExecute(String result) {
textView.setText(result);
}
}
...
}
The sequence of events in this snippet is as follows:
这个实例代码执行的逻辑顺序是:
- When users click the button that invokes
myClickHandler()
, the app passes the specified URL to theAsyncTask
subclassDownloadWebpageTask
.
当用户点击一个按钮后,会调用myClickHandler
方法,在这个方法中,会将指定的要下载的链接传递给AsyncTask类的子类DownloadWebpageTask
。
2. The AsyncTask
method doInBackground()
calls the downloadUrl()
method.
AsyncTask类的方法doInBackground
会调用downloadUrl
方法。
3. The downloadUrl()
method takes a URL string as a parameter and uses it to create a URL
object.
downloadUrl
方法将下载页面的地址作为参数,并以此参数创建一个URL对象。
4. The URL
object is used to establish an HttpURLConnection
.
再使用这个URL对象创建一个HttpURLConnection
连接。
5. Once the connection has been established, the HttpURLConnection
object fetches the web page content as an InputStream
.
一旦这个连接建立,HttpURLConnection
对象下载网页内容,并且将网页内容作为流;
6. The InputStream
is passed to the readIt()
method, which converts the stream to a string.
网页流再次传递给readIt
方法,在readIt
方法中,会将网页流转换为字符串。
7. Finally, the AsyncTask
's onPostExecute()
method displays the string in the main activity's UI.
最后,AsyncTask的onPostExecute方法会将这个转换后额字符串显示在界面上。
Connect and Download Data
In your thread that performs your network transactions, you can use HttpURLConnection
to perform a GET
and download your data. After you call connect()
, you can get an InputStream
of the data by callinggetInputStream()
.
在线程中执行网络操作时,你可以使用HttpURLConnection
这个类来执行get操作,以下载网页内容。当你调用了connect方法,再次调用getInputStream方法时,你就可以获取网页内容的流了。
In the following snippet, the doInBackground()
method calls the method downloadUrl()
. ThedownloadUrl()
method takes the given URL and uses it to connect to the network via HttpURLConnection
. Once a connection has been established, the app uses the method getInputStream()
to retrieve the data as anInputStream
.
在下面的实例中,doInBackground方法会调用downloadUrl
方法。downloadUrl
以指定的要下载的网页地址为参数,通过HttpURLConnection
来连接到这个网页。一旦连接建立了,就可以使用getInputStream
方法来获取网页流数据了。
// Given a URL, establishes an HttpUrlConnection and retrieves
// the web page content as a InputStream, which it returns as
// a string.
private String downloadUrl(String myurl) throws IOException {
InputStream is = null;
// Only display the first 500 characters of the retrieved
// web page content.
int len = 500; try {
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
int response = conn.getResponseCode();
Log.d(DEBUG_TAG, "The response is: " + response);
is = conn.getInputStream(); // Convert the InputStream into a string
String contentAsString = readIt(is, len);
return contentAsString; // Makes sure that the InputStream is closed after the app is
// finished using it.
} finally {
if (is != null) {
is.close();
}
}
}
Note that the method getResponseCode()
returns the connection's status code. This is a useful way of getting additional information about the connection. A status code of 200 indicates success.
记住,getResponseCode
返回创建连接时的服务器的响应。这是一个获取额外信息的方法。200一般表示连接成功。
Convert the InputStream to a String
An InputStream
is a readable source of bytes. Once you get an InputStream
, it's common to decode or convert it into a target data type. For example, if you were downloading image data, you might decode and display it like this:
InputStream
就是可读的字节序列。一旦你获取了InputStream
,一般而言,你需要将其解码或者转化为一个具体的类型。即,字节序列谁都看不懂,要把它转化成有意义的东西,比如字符串,位图等。比如,如果你下载了一个图片,你需要解码这个字节序列成图片,并且显示这个图片:
InputStream is = null;
...
Bitmap bitmap = BitmapFactory.decodeStream(is);
ImageView imageView = (ImageView) findViewById(R.id.image_view);
imageView.setImageBitmap(bitmap);
In the example shown above, the InputStream
represents the text of a web page. This is how the example converts the InputStream
to a string so that the activity can display it in the UI:
在上述的例子中,InputStream
代表了网页的文本内容。下面的代码显示了如何将InputStream
转化为字符串的,这样activity就可显示这个字符串了:
// Reads an InputStream and converts it to a String.
public String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException {
Reader reader = null;
reader = new InputStreamReader(stream, "UTF-8");
char[] buffer = new char[len];
reader.read(buffer);
return new String(buffer);
}
总结:
1. 与网络相关的操作放在单独的线程中,如可以使用AsyncTask类的子类,实现doInBackground方法和onPostExecuter方法;
2. 判断下当前用户设备是否已经连接上网络了,以及网络的连接状态,比如,移动网络是否已经打开,wifi是否已经打开;
3. 根据下载的网页地址URL创建HttpUrlConnection类,HttpUrlConnection.connect建立连接。
4. 记住,关闭inputStream流;
5. 将返回的网页流数据解码为有意义的东西。
Connecting to the Network的更多相关文章
- Network authentication method and device for implementing the same
A network authentication method is to be implemented using a network authentication device and a use ...
- Ethical Hacking - NETWORK PENETRATION TESTING(1)
Pre--Connection-Attacks that can be done before connecting to the network. Gaining Access - How to b ...
- Maven 代理设置
在maven的安装目录下 %MAVEN_HOME%/conf/setting.xml 中进行设置 <proxies> <!-- proxy | Specificatio ...
- 解决maven下载jar慢的问题(如何更换Maven下载源)
修改 配置文件 maven 安装 路径 F:\apache-maven-3.3.9\conf 修改 settings.xml 在 <mirrors> <!-- mirror | Sp ...
- maven学习(上)- 基本入门用法
一.下载及安装 1.1 下载maven 3.1.1 先到官网http://maven.apache.org/download.cgi 下载最新版本(目前是3.1.1 ),下载完成后,解压到某个目录(本 ...
- Maven日常 —— 你应该知道的一二三
以前在日常工作中,使用Maven只是机械的执行Maven clean.Maven install,对其中的原理与过程并无了解,近期阅读了<Maven实战>,对Maven有了更深入的理解. ...
- Maven配置Nexus私服
官方文档:http://books.sonatype.com/nexus-book/3.0/reference/maven.html#maven-sect-single-group 1,下载安装 首先 ...
- maven私服搭建
一.软件安装 地址:http://www.sonatype.org/nexus/thank-you-for-downloading/?dl=tgz 解压: 启动: >> nexus sta ...
- maven settings.xml 阿里云
<?xml version="1.0" encoding="UTF-8"?> <!--Licensed to the Apache Softw ...
随机推荐
- MFC应用程序配置不正确解决方案(manifest对依赖的强文件名,WinSxs是windows XP以上版本提供的非托管并行缓存)
[现象] 对这个问题的研究是起源于这么一个现象:当你用VC++2005(或者其它.NET)写程序后,在自己的计算机上能毫无问题地运行,但是当把此exe文件拷贝到别人电脑上时,便不能运行了,大致的错误提 ...
- [UWP-小白日记16]UWP中的3D变换API
原文:[UWP-小白日记16]UWP中的3D变换API 还没开始 好久没写博客了,再来开坑. 正文 Transform3D:“这个和CSS的3D好像的说” PerspectiveTransform3D ...
- C# 实现系统关机、注销、重启、休眠、挂起
原文:C# 实现系统关机.注销.重启.休眠.挂起 核心代码如下: using System; using System.Text; using System.Diagnostics; using Sy ...
- Android Studio 添加 Genymotion插件
原文:Android Studio 添加 Genymotion插件 1.下载Genymotion:官网地址,必须先注册才能下载,下载带有VirtualBox的版本 2.安装:安装时会连VirtualB ...
- C#正则表达式简单案例解析
正则表达式主要用于字符串的操作. 1.Regex.IsMatch:判断指定的字符串是否符合正则表达式. 2.Regex.Match:提取匹配的字符串,只能提取到第一个符合的字符串.这里还可以使用组来提 ...
- reset.css(样式重置)
CSS Reset,意为重置默认样式.HTML中绝大部分标签元素在网页显示中都有一个默认属性值,通常为了避免重复定义元素样式,需要进行重置默认样式(CSS Reset).举几个例子:1.淘宝(CSS ...
- java集合的方法及使用详解
一.java集合的分类及相互之间的关系 Collection接口:向下提供了List和Set两个子接口 |------List接口:存储有序的,存储元素可以重复 |------ArrayList(主要 ...
- python发送邮件554DT:SPM已解决
说明:本例使用163邮箱 一.报错信息 使用SMTP发送邮件遇到以下报错: 554, b'DT:SPM 163 smtp10,DsCowACXeOtmjRRdsY8aCw--.21947S2 1561 ...
- YARN分析系列之一 -- 总览YARN组件
下图简单明了的描述了hadoop yarn 的功能是如何从 hadoop 中细化出来的. 注:图片来自 https://apprize.info/php/hadoop/9.html Hadoop 从 ...
- 高并发 Nginx+Lua OpenResty系列(8)——Lua模版渲染
模版渲染 动态web网页开发是Web开发中一个常见的场景,比如像京东商品详情页,其页面逻辑是非常复杂的,需要使用模板技术来实现.而Lua中也有许多模板引擎,如目前京东在使用的lua-resty-tem ...