注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好。

原文链接:http://developer.android.com/training/basics/network-ops/connecting.html


这节课将会向你展示如何实现一个简单地连接网络的应用。这当中包含了一些创建哪怕是最简单的网络连接应用时需要遵循的最佳实践规范。

注意,要执行这节课中所讲的网络操作,你的应用清单必须包含如下的权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

一). 选择一个HTTP客户端

大多数带有网络连接的Android应用使用HTTP来发送和接收数据。Android包含了两个HTTP客户端:HttpURLConnection,以及Apache HttpClient。两者都支持HTTPS,数据流的上传和下载,可配置的超时限定,IPv6,以及连接池。对于适用于Gingerbread及更高系统的应用,我们推荐使用HttpURLConnection。更多关于这方面的信息,可以阅读Android's HTTP Clients


二). 检查网络连接

当你的应用尝试连接到网络时,它应该使用getActiveNetworkInfo()isConnected()来检查当前是否有一个可获取的网络连接。这是因为,该设备可能会超出网络的覆盖范围,或者用户将Wi-Fi和移动数据连接都禁用的。更多关于该方面的知识,可以阅读Managing Network Usage

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线程之外的另一个线程上执行。AsyncTask类提供了一个最简单的方法来启动一个UI线程之外的新线程。想知道有关这方面的内容,可以阅读:Multithreading For Performance

在下面的代码中,myClickHandler()方法调用new DownloadWebpageTask().execute(stringUrl)。DownloadWebpageTask类是AsyncTask的子类,它实现下列AsyncTask中的方法:

  • doInBackground() - 执行downloadUrl()方法。它接受网页的URL作为一个参数。该方法获取并处理网页内容。当它结束后,它会返回一个结果字符串。
  • onPostExecute() - 接收返回的字符串并将结果显示在UI上。
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 DownloadWebpageTask().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 DownloadWebpageTask extends AsyncTask<String, Void, String> {
@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);
}
}
...
}

在上述代码中,事件的发生流程如下:

当用户点击按钮激活myClickHandler()后,应用会将指定的URL传递给AsyncTask的子类DownloadWebpageTask。

AsyncTask中的方法doInBackground()调用downloadUrl()方法。

downloadUrl()方法接收一个URL字符串作为参数并使用它来创建一个URL对象。

URL对象用来建立一个HttpURLConnection

一旦连接建立完成,HttpURLConnection对象取回网页内容,并将其作为一个InputStream

InputStream传递给readIt()方法,它将其转换为String。

最后AsyncTaskonPostExecute()方法将结果显示在主activity的UI上。


四). 连接并下载数据

在你的执行网络交互的线程中,你可以使用HttpURLConnection来执行一个GET,并下载你的数据。在你调用了connect()之后,你可以通过调用getInputStream()来获得数据的InputStream

在下面的代码中,doInBackground()方法调用downloadUrl()。后者接收URL参数,并使用URL通过HttpURLConnection连接网络。一旦一个连接建立了,应用将使用getInputStream()方法来获取InputStream形式的数据。

// 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();
}
}
}

注意方法getResponseCode()返回的是连接的状态码(status code)。这是一个非常有用的方法来获得关于连接的额外信息。状态码200意味着连接成功。


五). 将InputStream转换为String

一个InputStream是一个可读的字节源。一旦你获得了一个InputStream,通常都需要将它解码或转换成你需要的数据类型。例如,如果你正在下载图像数据,你可能会这样对它进行解码:

InputStream is = null;
...
Bitmap bitmap = BitmapFactory.decodeStream(is);
ImageView imageView = (ImageView) findViewById(R.id.image_view);
imageView.setImageBitmap(bitmap);

在上面的例子中,InputStream代表了一个网页的文本。下面的例子是将InputStream转换为String,这样activity可以在UI中显示它:

// 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);
}

【Android Developers Training】 79. 连接到网络的更多相关文章

  1. 【Android Developers Training】 80. 管理网络使用

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  2. 【Android Developers Training】 78. 序言:执行网络操作

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  3. 【Android Developers Training】 86. 基于连接类型修改您的下载模式

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  4. 【Android Developers Training】 83. 实现高效网络访问来优化下载

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  5. 【Android Developers Training】 76. 用Wi-Fi创建P2P连接

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  6. 【Android Developers Training】 108. 使用模拟定位进行测试

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  7. 【Android Developers Training】 106. 创建并检测地理围栏

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  8. 【Android Developers Training】 104. 接受地点更新

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  9. 【Android Developers Training】 96. 运行一个同步适配器

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

随机推荐

  1. 【JAVAWEB学习笔记】06_jQuery基础

    接05的学习笔记. 四.使用JQ完成省市二级联动 1.需求分析 使用jquery完成省市二级联动 2.技术分析 2.1数组的遍历操作 方式一: $(function(){ // 全选/ 全不选 $(& ...

  2. JVM方法调用

    当我们站在JVM实现的角度去看方法调用的时候,我们自然会想到一种分类: 1.编译代码的时候就知道是哪个方法,永远不会产生歧义,例如静态方法,private方法,构造方法,super方法. 2.运行时才 ...

  3. 取代netcat

    前言 众所周知,netcat是网络界的瑞士军刀,它的主要作用是:提供连接其他终端的方法,可以上传文件,反弹shell等等各种利于别人控制你电脑的操作.所以聪明的系统管理员会将它从系统中移除,这样当别人 ...

  4. ArrayList源码解析(二)自动扩容机制与add操作

    本篇主要分析ArrayList的自动扩容机制,add和remove的相关方法. 作为一个list,add和remove操作自然是必须的. 前面说过,ArrayList底层是使用Object数组实现的. ...

  5. 如何选择版本控制系统之二---Git的研发应用场

    之前写了一篇<如何选择版本控制系统 ---为什么选择Git版本控制系统>,地址是:http://www.cnblogs.com/goldenfish/p/6876864.html,有兴趣的 ...

  6. HIVE安装配置

    Hive简介 Hive 基本介绍 Hive 实现机制 Hive 数据模型 Hive 如何转换成MapReduce Hive 与其他数据库的区别 以上详见:https://chu888chu888.gi ...

  7. git使用简易指南

    安装 下载 git OSX 版 下载 git Windows 版 下载 git Linux 版 创建新仓库 创建新文件夹,打开,然后执行 git init 以创建新的 git 仓库. 检出仓库 执行如 ...

  8. 基于类(Java)和基于原理(JavaScript)的对象系统的比较

    Java:面向对象编程语言,吸收了C++语言的各种优点,丢掉了C++让人头疼的多继承.指针等概念.具有功能强大和简单易用的两大特征.Java具有简单性.面向对象.分布式.健壮性.安全性.平台独立与可移 ...

  9. yarn工作流程

    YARN 是 Hadoop 2.0 中的资源管理系统, 它的基本设计思想是将 MRv1 中的 JobTracker拆分成了两个独立的服务 : 一个全局的资源管理器 ResourceManager 和每 ...

  10. scrapy跟pyspider的杂谈

    最近有一个私人项目要搞,可能最近的博客都会变成爬虫跟数据分析类的了.既然是爬虫,第一反应想到的就是鼎鼎大名的scrapy了,其次想到的pyspider,最后想到的就是自己写. scrapy是封装了tw ...