Android官方开发文档Training系列课程中文版:网络操作之网络连接

简介: 原文地址:http://android.xsoftlab.net/training/basics/network-ops/index.html引言这节课将会学习最基本的网络连接,监视网络连接状况及网络控制等内容。

原文地址:http://android.xsoftlab.net/training/basics/network-ops/index.html

引言

这节课将会学习最基本的网络连接,监视网络连接状况及网络控制等内容。除此之外还会附带描述如何解析、使用XML数据。

这节课所包含的示例代码演示了最基本的网络操作过程。开发者可以将这部分的代码作为应用程序最基本的网络操作代码。

通过这节课的学习,将会学到最基本的网络下载及数据解析的相关知识。

Note: 可以查看课程Transmitting Network Data Using Volley学习Volley的相关知识。这个HTTP库可以使网络操作更方便更快捷。Volley是一个开源框架库,可以使应用的网络操作顺序更加合理并善于管理,还会改善应用的相关性能。

连接到网络

这节课将会学习如何实现一个含有网络连接的简单程序。课程中所描述的步骤是网络连接的最佳实现过程。

如果应用要使用网络操作,那么清单文件中应该包含以下权限:

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

选择HTTP客户端

大多数的Android应用使用HTTP来发送、接收数据。Android中包含了两个HTPP客户端:HttpURLConnection及Apache的HTTP客户端。两者都支持HTTPS,上传,下载,超时时间配置,IPv6,连接池。我们推荐在Gingerbread及以上的版本中使用HttpURLConnection。有关这个话题的更多讨论信息,请参见博客Android’s HTTP Clients.

检查网络连接状况

在尝试连接到网络之前,应当通过getActiveNetworkInfo()方法及isConnected()方法检查网络连接是否可用。要记得,设备可能处于不在网络范围的情况中,也可能用户并没有开启WIFI或者移动数据。该话题的更多信息请参见 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
    }
    ...
}

在子线程中执行网络操作

网络操作所用的时间通常是不确定的。为了防止由于网络操作而引起的糟糕的用户体验,应该将这个过程放入独立的线程中执行。AsyncTask类为这种实现提供了帮助。更多该话题的讨论请参见Multithreading For Performance

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

  • doInBackground()中执行了downloadUrl()方法。它将Web页的URL地址作为参数传给了该方法。downloadUrl()方法会获得并处理Web页面的内容。当处理结束时,这个方法会将处理后的结果返回。
  • 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);
       }
    }
    ...
}

上面的代码执行了以下操作:

  • 1.当用户按下按钮时会调用myClickHandler()方法,应用会将指定的URL地址传递给DownloadWebpageTask。
  • 2.DownloadWebpageTask的doInBackground()方法调用了downloadUrl()方法。
  • 3.downloadUrl()方法将获得的URL字符串作为参数创建了一个URL对象。
  • 4.URL对象被用来与HttpURLConnection建立连接。
  • 5.一旦连接建立,HttpURLConnection会将获取到的Web页面内容作为输入流输入。
  • 6.readIt()方法将输入流转换为String对象。
  • 7.最后onPostExecute()方法将String对象显示在UI上。

连接与下载数据

在执行网络传输的线程中可以使用HttpURLConnection来执行GET请求并下载输入。在调用了connect()方法之后,可以通过getInputStream()方法获得输入流形式的数据。

在doInBackground()方法中调用了downloadUrl()方法。downloadUrl()方法将URL作为参数通过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();
        } 
    }
}

注意getResponseCode()方法返回的是连接的状态码。该状态码可以用来获取连接的其它信息。状态码为200则表明连接成功。

将字节流转换为字符串

InputStream所读取的是字节数据。一旦获得InputStream对象,通常需要将其解码或者转化为其它类型的数据。比如,如果下载了一张图片,则应该将字节流转码为图片:

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

在上的示例中,InputStream代表了Web页面的文本内容。下面的代码展示了如何将字节流转换为字符串:

// 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);
}
目录
相关文章
|
15天前
|
机器学习/深度学习 Serverless 文件存储
函数计算操作报错合集之在网络设置完成后进行挂载的指令,报错:找不到网络路径,该如何处理
在使用函数计算服务(如阿里云函数计算)时,用户可能会遇到多种错误场景。以下是一些常见的操作报错及其可能的原因和解决方法,包括但不限于:1. 函数部署失败、2. 函数执行超时、3. 资源不足错误、4. 权限与访问错误、5. 依赖问题、6. 网络配置错误、7. 触发器配置错误、8. 日志与监控问题。
|
18天前
|
缓存 网络协议 安全
Android网络面试题之Http基础和Http1.0的特点
**HTTP基础:GET和POST关键差异在于参数传递方式(GET在URL,POST在请求体),安全性(POST更安全),数据大小限制(POST无限制,GET有限制),速度(GET较快)及用途(GET用于获取,POST用于提交)。面试中常强调POST的安全性、数据量、数据类型支持及速度。HTTP 1.0引入了POST和HEAD方法,支持多种数据格式和缓存,但每个请求需新建TCP连接。**
23 5
|
16天前
|
安全 网络协议 算法
Android网络基础面试题之HTTPS的工作流程和原理
HTTPS简述 HTTPS基于TCP 443端口,通过CA证书确保服务器身份,使用DH算法协商对称密钥进行加密通信。流程包括TCP握手、证书验证(公钥解密,哈希对比)和数据加密传输(随机数加密,预主密钥,对称加密)。特点是安全但慢,易受特定攻击,且依赖可信的CA。每次请求可能复用Session ID以减少握手。
24 2
|
22天前
|
缓存 JSON 网络协议
Android面试题:App性能优化之电量优化和网络优化
这篇文章讨论了Android应用的电量和网络优化。电量优化涉及Doze和Standby模式,其中应用可能需要通过用户白名单或电池广播来适应限制。Battery Historian和Android Studio的Energy Profile是电量分析工具。建议减少不必要的操作,延迟非关键任务,合并网络请求。网络优化包括HTTPDNS减少DNS解析延迟,Keep-Alive复用连接,HTTP/2实现多路复用,以及使用protobuf和gzip压缩数据。其他策略如使用WebP图像格式,按网络质量提供不同分辨率的图片,以及启用HTTP缓存也是有效手段。
40 9
|
17天前
|
缓存 网络协议 Android开发
Android网络面试题之Http1.1和Http2.0
HTTP/1.1 引入持久连接和管道机制提升效率,支持分块传输编码和更多请求方式如PUT、PATCH。Host字段指定服务器域名,RANGE用于断点续传。HTTP/2变为二进制协议,实现多工处理,头信息压缩和服务器推送,减少延迟并优化资源加载。HTTP不断发展,从早期的简单传输到后来的高效交互。
21 0
Android网络面试题之Http1.1和Http2.0
|
17天前
|
缓存 NoSQL Redis
redis管道操作(节省网络IO开销)
pipeline中发送的每个command都会被server立即执行,如果执行失败,将会在此后的响应中得到信息;也就是pipeline并不是表达“所有command都一起成功”的语义,管道中前面命令失败,后面命令不会有影响,继续执行。
17 1
|
26天前
|
缓存 网络协议 Java
Android面试题之Java网络通信基础知识
Socket是应用与TCP/IP通信的接口,封装了底层细节。网络通信涉及连接、读写数据。BIO是同步阻塞,NIO支持多路复用(如Selector),AIO在某些平台提供异步非阻塞服务。BIO示例中,服务端用固定线程池处理客户端请求,客户端发起连接并读写数据。NIO的关键是Selector监控多个通道的事件,减少线程消耗。书中推荐《Java网络编程》和《UNIX网络编程》。关注公众号AntDream了解更多。
23 2
|
26天前
|
XML JSON Java
Android面试题 之 网络通信基础面试题
序列化对比:Serializable码流大、性能低;XML人机可读但复杂;JSON轻量、兼容性好但空间消耗大;ProtoBuff高效紧凑。支持大量长连接涉及系统限制调整、缓冲区优化。select/poll/epoll是IO多路复用,epoll在高连接数下性能更优且支持边缘触发。水平触发持续通知数据,边缘触发仅通知新数据。直接内存减少一次拷贝,零拷贝技术如sendfile和MMAP提升效率。关注公众号&quot;AntDream&quot;了解更多技术细节。
16 1
|
1月前
|
安全 Android开发 数据安全/隐私保护
同样的 APP 为何在 Android 8 以后网络感觉变卡?
【6月更文挑战第8天】Android 8 及以后系统中,APP 网络感觉变卡源于更严格的安全机制和后台限制,系统对网络优化的侧重改变,以及APP自身兼容性问题。开发者需优化APP,适应新系统,用户可更新APP或检查权限设置。通过共同努力,有望改善网络卡顿现象,提升用户体验。
|
17天前
|
安全 Java API
Android获取Wi-Fi网络列表
【6月更文挑战第21天】