注:本文翻译自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。

最后AsyncTask的onPostExecute()方法将结果显示在主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. 如何用Ettercap实现“中间人攻击”(附下载链接)

    什么是“中间人攻击”? 中间人攻击(Man-in-the-Middle Attack,简称“MiTM攻击”)是一种“间接”的入侵攻击,这种攻击模式是通过各种技术手段将受入侵者控制的一台计算机虚拟放置在 ...

  2. Java学习笔记——设计模式之一.简单工厂

    蜀道之难.难于上青天,侧身西望长咨嗟 --蜀道难 设计模式第一篇,简单工厂. 定义Operation类 package cn.no1.simplefactory; public abstract cl ...

  3. 建造者(Builder)模式

    建造者模式是对象的创建模式.建造模式可以将一个产品的内部表象(internal representation)与产品的生产过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象. 产品的 ...

  4. spring---简介

    spring spring是什么? 目的:解决企业应用开发的复杂性 功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能 范围:任何Java应用 简单来说,Spring是一个轻量级的 ...

  5. Natas Wargame Level 19 Writeup(猜测令牌,会话劫持)

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAq4AAAEKCAYAAADTmtdjAAAABHNCSVQICAgIfAhkiAAAIABJREFUeF

  6. Linux-Zabbix 邮件报警设置

    系统环境 Ubuntu 16.04 在Zabbix服务器端 安装sendmail sudo apt install sendmail 测试发送邮件 echo "正文!" | mai ...

  7. 关于bootstrap table 的可编辑列表的实例

    最近被安排到一个新的项目里,首先被分配了一个成果管理的模块,虽然是简单的增删改查,但是也费了不少功夫. 其中耽误最长的时间就是form中嵌套了两个可编辑列表的子表.废话不说上干货 = = 参考资料 1 ...

  8. Javascript版-显示相应图片的详细信息

    Hi All, 分享一个通过JS来显示相应图片的详细信息. 需求:进入页面时,动态加载图片信息:当鼠标移动到某一图片上时,则显示该图片的大图片并显示相应说明信息:当鼠标移开图片时,清除新创建的元素. ...

  9. 模仿ICE的structured panorama小按钮

    这个按钮的目的是用于手动排列图片序列,应该说写得比较精巧,我使用csharp进行模仿,主要采用的是自动控件创建技术.结果比较简陋,实现功能而已,放出来大家一起学习. ;        ;        ...

  10. VR全景智慧城市--2017年VR项目加盟将是一个机遇

    全景智慧城市项目是河南艺境空间文化传播有限公司自主开发的国内第一家商业全景平台, 旨在构建全景城市,实现智慧生活,让人们随时随地身临其境拥有全世界,享受快捷.真实.趣味.优质生活. 以VR虚拟现实技术 ...