【Android Developers Training】 79. 连接到网络
注:本文翻译自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. 连接到网络的更多相关文章
- 【Android Developers Training】 80. 管理网络使用
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- 【Android Developers Training】 78. 序言:执行网络操作
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- 【Android Developers Training】 86. 基于连接类型修改您的下载模式
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- 【Android Developers Training】 83. 实现高效网络访问来优化下载
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- 【Android Developers Training】 76. 用Wi-Fi创建P2P连接
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- 【Android Developers Training】 108. 使用模拟定位进行测试
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- 【Android Developers Training】 106. 创建并检测地理围栏
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- 【Android Developers Training】 104. 接受地点更新
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- 【Android Developers Training】 96. 运行一个同步适配器
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
随机推荐
- c#接口使用详解
c#接口使用详解 c#中接口隐式与显示实现 c#中接口可以隐式实现.显示实现,隐式实现更常使用.显示实现较少使用 其区别在于 显示实现避免接口函数签名冲突 显示实现只可以以接口形式调用 显示实现其子类 ...
- crontab的相关设置&linux定时备份数据库
对于才了解crontab的人来说,应该按照以下的步骤来设置crontab 1.首先要检查是否装了crontab http://blog.sina.com.cn/s/blog_4881040d01011 ...
- Windows 2008 R2下 如何简单使用IIS来配置PHP网站
虽然PHP网站配置一般大多数人可能会联想到用Apache+php+mysql来配置,但是呢,如果是为了安全性考虑或者是说是为了便捷高效快速的完成工作,那么Apache+php+mysql这个配置工作就 ...
- 最近项目用到Dubbo框架,分享一下~
1. Dubbo是什么? Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案.简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需 ...
- ASP.NET Core 菜鸟之路:从Startup.cs说起
1.前言 本文主要是以Visual Studio 2017 默认的 WebApi 模板作为基架,基于Asp .Net Core 1.0,本文面向的是初学者,如果你有 ASP.NET Core 相关实践 ...
- rpm不用yum安装rabbitMQ
1.安装erlang 下载 esl-erlang_19.0~centos~6_amd64.rpm 打开https://www.erlang-solutions.com/resources/downlo ...
- 利用EF ORM Mysql实体运行程序出错解决方案
程序环境:VS2013 + mysql (server 5.7 + connector net 6.9.9 + for visual studio 1.2.6) + entity framework ...
- Reinforcement Learning in R
Reinforcement learning has gained considerable traction as it mines real experiences with the help o ...
- C#基础篇--静态成员、抽象成员、接口
1.静态成员: 静态成员(static).静态类与实例成员.类: 静态成员属于类所有,非静态成员属于类的实例所有. 静态成员不能标记为 Virtual,Abstract,Override,也就是说静态 ...
- RavenDB FS 安装使用 介绍
前言 最近项目因为要存储图片和文件,折腾了RavenDB,使用RavenDB的FS系统统一管理图片和文件. 安装 RavenDB 的FS文件系统,需要用到windows的远程差分压缩功能: 安装好之后 ...