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

原文地址: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);
}
时间: 2024-12-26 11:37:06

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

Android官方开发文档Training系列课程中文版:目录

原文地址 : http://android.xsoftlab.net/training/index.html 引言 在翻译了一篇安卓的官方文档之后,我觉得应该做一件事情,就是把安卓的整篇训练课程全部翻译成英文,供国内的开发者使用,尤其是入门开发者,虽然现在网络上有很多入门课程,但是还是依靠官方文档学习来的靠谱,安卓官方文档是一系列的课程,使每个人可以系统的掌握安卓的知识,相比其它课程来说,它为开发者提供了查缺补漏的功能. 在这里你可以领略到安卓开发世界的精彩. Tips : 同时,本目录可以作为

Android官方开发文档Training系列课程中文版:OpenGL绘图之图形绘制

原文地址:http://android.xsoftlab.net/training/graphics/opengl/draw.html 如果你还不清楚如何定义图形及坐标系统,请移步:Android官方开发文档Training系列课程中文版:OpenGL绘图之图形定义. 在定义了图形之后,你接下来需要做的就是将它绘制到屏幕上.不过使用OpenGL ES 2.0 API来绘制这个图形所需要的代码量可能要比想象中的多一些,这是因为API为图形渲染管道提供了大量的控制细节. 这节课会展示如何绘制上节课所

Android官方开发文档Training系列课程中文版:通知用户之构建通知

原文地址:http://android.xsoftlab.net/training/notify-user/index.html 引言 通知用于在有事件发生时,将事情以更便捷的方式展示给用户.用户可以在他们方便的时候直接与通知交互. Notifications design guide课程讲述了如何设计有效的通知以及何时去使用它们.这节课将会学习如何实现通用的通知设计. 构建通知 这节课的实现主要基于NotificationCompat.Builder类,NotificationCompat.B

Android官方开发文档Training系列课程中文版:手势处理之多点触控处理

原文地址:http://android.xsoftlab.net/training/gestures/multi.html 多点触控是指多个手指同时触摸屏幕的情况.这节课主要学习如何检测多点触控手势. 记录多个触控点 当多根手指同时触碰到屏幕时,系统会产生以下触摸事件: ACTION_DOWN -第一个触碰到屏幕的点.它是手势的起始事件.这个触控点的指针数据在MotionEvent对象中的索引总是0. ACTION_POINTER_DOWN -除第一个触控点之外的其它点.这个触控点的指针数据的索

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

原文地址:http://android.xsoftlab.net/training/basics/network-ops/xml.html 扩展标记语言(XML)是一系列有序编码的文档.它是一种很受欢迎的互联网数据传输格式.像需要频繁更新内容的网站来说,比如新闻站点或者博客,需要经常更新它们的XML源,以使外部程序可以保持内容的同步变化.对于含有网络连接态的APP应用来说,上传及解析XML数据是一个通用的任务.这节课将会学习如何解析XML文档及如何使用XML中的数据. 选择解析器 我们推荐使用X

Android官方开发文档Training系列课程中文版:动画视图之转场框架介绍

原文地址:http://android.xsoftlab.net/training/transitions/index.html 引言 Activity所呈现的UI经常会由用户的输入或者其它事件而发生变化.比如,一个含有输入框的Activity,在用户输入要查找的关键字之后,这个输入框就会隐藏,并会在输入框的地方展示搜索后的结果. 为了可以在这样的情况下呈现出连贯的视觉效果,可以在不同View展示与隐藏过程中使用动画.这些动画可以为用户提供一种反馈,并会帮助他们学习应用是如何流转的. Andro

Android官方开发文档Training系列课程中文版:性能优化建议

原文地址:http://android.xsoftlab.net/training/articles/perf-tips.html 本篇文章主要介绍那些可以提升整体性能的微小优化点.它与那些能突然改观性能效果的优化手段并不属于同一类.选择正确的算法与数据结构必然是我们的第一总则,但是这不是我们这篇文章要介绍的.你应该将这篇文章所提及的知识点作为编码的日常习惯,这可以提升常规代码的执行效率. 下面是书写代码的基本准则: 绝不要做你不需要的工作. 如果可以不申请内存就不要申请,要合理复用已有的对象.

Android官方开发文档Training系列课程中文版:OpenGL绘图之环境配置

原文地址:http://android.xsoftlab.net/training/graphics/opengl/index.html 引言 Android framework层为创建绚丽的功能性UI提供了大量的标准工具.然而,如果想要以更多方式来控制屏幕的绘制,或者在三维图形中绘制,那么就需要使用其它工具了.Android framework所提供的OpenGL ES API为我们提供了一系列的工具,这些工具可以用来显示一些高端大气.天马行空的图形,只要你能想得到,那么它就可以做得到.此外,

Android官方开发文档Training系列课程中文版:打印内容之自定义文档打印

原文地址:http://android.xsoftlab.net/training/printing/custom-docs.html 对于一些应用,比如绘图类APP,版面设计类APP以及其它APP,这些APP都关注图形的输出,有一个漂亮的打印页面是它们的关键特性.在这种情况下,就不单单是打印一张图片或者是HTML文档这么简单了.这些程序对于这种类型的打印需要对页面中每样事物的控制都特别的精细,包括字体.文本流.页面间距.页眉.页脚以及图形元素. 创建打印输出对于程序来说是完全自定义的,这需要更