• 第一行代码 Android 第九章9.1-9.2(WebView的用法,使用HttpURLConnect发送HTTP请求,使用OkHttp发送HTTP请求)


    第九章 看看精彩世界——使用网络技术        
            我们需要考虑如何利用网络来编写更加出色的应用程序,像qq,微博,微信等常见的应用都会大量使用网络技术。本章主要将入如何在手机端使用HTTP协议和服务器进行网络交互,并对服务器返回的数据进行解析,这也是Android中最常使用到的网络技术。

    9.1 WebView的用法
            有时候我们可能会碰到一些比较特殊的需求,比如说要求在应用程序里展示一些网页。但是需求里又明确指出,不允许打开系统浏览器,而我们当然也不可能自己去编写一个浏览器出来,这时候怎么办呢?
            Android提供了一个WebView控件,借助它我们就可以在自己的应用程序里嵌入一个浏览器,从而非常轻松的展示各种各样的网页。

    1. //新建一个WebViewTest项目
    2. //修改activity_main文件
    3. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    4. android:layout_width="match_parent"
    5. android:layout_height="match_parent" >
    6. <WebView //给它设置一个id,并让它充满整个屏幕
    7. android:id="@+id/web_view"
    8. android:layout_width="match_parent"
    9. android:layout_height="match_parent" />
    10. LinearLayout>
    1. //这段代码的作用是,当需要从一个网页跳转到另一个网页时,我们希望目标网页仍然在当前WebView中显示,而不是打开浏览器
    2. public class MainActivity extends AppCompatActivity {
    3. @Override
    4. protected void onCreate(Bundle savedInstanceState) {
    5. super.onCreate(savedInstanceState);
    6. setContentView(R.layout.activity_main);
    7. WebView webView = (WebView) findViewById(R.id.web_view);
    8. webView.getSetting().setJavaScriptEnabled(true); //getSetting设置浏览器属性,setJavaScriptEnabled让WebView支持JavaScript脚本
    9. webView.setWebViewClient(new WebViewClient()); //调用setWebViewClient来获取WebViewClient的实例
    10. webView.loadUrl("http://www.baidu.com");
    11. }
    12. }
    1. //最后需要注意的是,由于本程序使用到了网络功能,而访问网络是需要声明权限的,因此我们还需要修改AndroidManifest文件
    2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    3. package="com.example.webviewtest">
    4. <user-permission android:name="android.perrmission.INTERNET" />
    5. ...
    6. manifest>

    9.2 使用HTTP协议访问网络
            HTTP协议的工作原理非常简单,就是客户端向服务器发出一条HTTP请求,服务器收到请求之后会返回一些数据给客户端,然后客户端再对这些数据进行解析和处理就可以了。
            WebView以及在后台帮我们处理好了发送HTTP请求,接收服务响应,解析返回数据,以及最终的页面展示这几步工作,不过由于他封装的实在太好了,反而使得我们不能那么直观地看出HTTP协议到底是如何工作的。因此下面我们就使用手动发送HTTP请求的方式,来更加深入地理解一下这个过程。
    9.2.1 使用HttpURLConnection
            在过去,Android上发送HTTP请求一般有两种方式:HttpURLConnection和HttpClient。目前HttpClient的功能由于缺点太多在Android6.0中已经被完全移除了。

    HttpURLConnection的用法:

    1)首先需要获取到HttpURLConnection的实例,一般只需要new出一个URL对象,并传入目标的网络地址,然后调用openConnection()方法即可
            URL url = new URL("http://www.baidu.com");

            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    2)得到HttpURLConnection实例后,可以设置HTTP请求方法
            GET:从服务器获取数据        POST:提交数据给服务器
            connection.setRequestMethod("GET");
    3)接下来就可以进行一些自由的定制,比如设置连接超时,读取超时的毫秒数。
            connection.setConnectTimeout(8000);  //连接超时
            connection.setReadTimeout(8000);   //读取超时的毫秒数
    4)之后再调用getInputStream()方法就可以获取到服务器返回的输入流了
            InputStream in = connection.getInputStream();
    5)  剩下的任务是对输入流进行读取
    6)最后调用disconnect()方法将这个HTTP连接关闭掉
            connection.disconnect();

    1. //新建一个NetworkTest项目
    2. //修改activity_main文件
    3. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    4. android:orientation="vertical"
    5. android:layout_width="match_parent"
    6. android:layout_height="match_parent" >
    7. <Button //用于发送HTTP请求
    8. android:id="@+id/send_request"
    9. android:layout_width="match_parent"
    10. android:layout_height="wrap_content"
    11. android:text="Send Request" />
    12. <ScrollView //借助ScrollView控件,实现以滚动的形式查看屏幕外的那部分内容
    13. android:layout_width="match_parent"
    14. android:layout_height="match_parent" >
    15. <TextView //用于将服务器返回的数据显示出来
    16. android:id="@+id/response_text"
    17. android:layout_width="match_parent"
    18. android:layout_height="wrap_content" />
    19. ScrollView>
    20. LinearLayout>
    1. //修改MainActivity中的代码
    2. public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    3. TextView responseText;
    4. @Override
    5. protected void onCreate(Bundle savedInstanceState) {
    6. super.onCreate(savedInstanceState);
    7. setContentView(R.layout.activity_main);
    8. Button sendRequest = (Button) findViewById(R.id.send_request);
    9. responseText = (TextView) findViewById(R.id.send_request);
    10. sendRequest.setOnClickListener(this);
    11. }
    12. @Override
    13. public void onClick(View v) {
    14. if (v.getId() == R.id.send_request) {
    15. sendRequestWithHttpURLConnection();
    16. }
    17. }
    18. private void sendRequestWithHttpURLConnection() {
    19. //开启线程来发起网络请求
    20. new Thread(new Runnable() { //开启子线程
    21. @Override
    22. public void run() {
    23. HttpURLConnection connection = null;
    24. BufferedReader reader = null;
    25. try {
    26. URL url = new URL("http://www.baidu.com");
    27. connection = (HttpURLConnection) url.openConnetion(); //获取连接对象
    28. connection.setRequestMethod("GET"); //设置请求方式
    29. connection.setConnectTimeout(8000); //设置连接的超时时间
    30. connection.setReadTimeout(8000); //设置传递数据的超时时间
    31. InputStream in = connection.getInputStream(); //获取服务器的响应流
    32. //下面对获取到的输入流进行读取
    33. reader = new BufferedReader(new InputStreamReader(in));
    34. StringBuilder reponse = new StringBuilder();
    35. String line;
    36. while((line = reader.readLine()) != null) {
    37. response.append(line); //一行行的读取追加到StringBuilder中
    38. }
    39. showResponse(response.toString()); //将方法子线程切换到主线程
    40. } catch (Exception e) {
    41. e.printStackTrace();
    42. } finally {
    43. if (reader != null) {
    44. try {
    45. reader.close();
    46. } catch {
    47. e.printStackTrace();
    48. }
    49. }
    50. if (connection != null) {
    51. connection.disconnect(); // 关闭连接
    52. }
    53. }
    54. }
    55. }).start();
    56. }
    57. private void showResponse(final String response) {
    58. runOnUiThread(new Runnable() {
    59. @Override
    60. public void run() {
    61. //在这里进行UI操作,将结果显示到界面上
    62. responseText.setText(response);
    63. }
    64. });
    65. }
    66. }
    1. //最后一定不能忘记声明网络权限
    2. <manifest ...>
    3. <user-permission android:name="android.permission.INTERNET"/>
    4. ...
    5. manifest>

    注意:如果想要提交数据给服务器,只需要将HTTP请求的方法改写成POST,并在获取输入流之前把要提交的数据写出即可。注意每条数据都要以键值对的形式存在,数据与数据之间用&隔开。

    1. //例如像服务器提交用户名和密码
    2. connection.setRequestMethod("POST");
    3. DataOutputStream out = new DataOUtputStream(connection.getOutputStream);
    4. out.writeBytes("username=admin&password=123456");

    9.2.2 使用OkHttp
            有许多出色的网络通信库都可以替代原生的HttpURLConnection,而其中OkHttp无疑是做的最出色的一个。
            OkHttp不仅在接口封装上面做的简单易用,就连在底层实现上也是自成一派。
            OkHttp的项目主页地址是:https://github.com/square/okhttp

    1)在使用OkHttp之前,我们需要先在项目中添加OkHttp库的依赖,编辑app/build.gradle文件

    dependencied {

            compile fileTree(dir:'libs,include:['*.jar'])
            compile 'com.android.support:appcompat-v7:24.2.1
            testCompile 'junit:junit:4.12'
            compile 'com.squareup.okhttp3:okhttp:3.4.1'

    }

    上述依赖会自动下载两个库,一个是OkHttp库一个是Okio库,后者是前者的通信基础

    2)接下来使用OkHttp需要创建一个OkHttpClient实例

            OkHttpClient client = new OkHttpClient();
    GET请求步骤:

    3)接下来如果想要发起一条HTTP请求,需要创建一个Request对象

            Request request = new Request.Builder().build();
    4)上述代码只是创建了一个空的Request对象,并没有什么实际作用,我们可以在最终的build方法之前连缀很多其他方法来丰富这个Request对象,比如可以通过url()方法来设置目标的网络地址
            Request request = new Request.Builder().url("http://www.baidu.com").build();

    POST请求步骤:

    3)需要先构建出一个RequestBody对象来存放待提交的参数
            RequestBody requestBody = new  FormBody.Builder().add("username","admin").add("password","123456").build();
    4)然后在Request.Bulder中调用一下post方法,并将RequestBody对象传入

            Request request = new Request.Builder().url("http://www.baidu.com").post(requestBody).build();

    5)之后调用OkHttpClient的newCall()方法来创建一个Call对象,并调用它的execute()方法来发送请求并获取服务器返回的数据
            Response response = client.newCall(request).execute();

    6)response就是服务器返回的数据
            String responseData = response.body().string();

     

    1. //修改MainActivity中的代码
    2. public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    3. ...
    4. @Override
    5. public void onCilck(View v) {
    6. if(v.getId() == R.id.send_request) {
    7. sendRequestWithOkHttp();
    8. }
    9. }
    10. private void sendRequestWithOkHttp() {
    11. new Thread(new Runnable() {
    12. @Override
    13. public void run() {
    14. try {
    15. OkHttpClient client = new OkHttpClient();
    16. Request request = new Request.Builder().url("http://www.baidu.com").build();
    17. Response response = client.newCall(request).execute();
    18. String responseData = reaponse.body().string();
    19. showResponse(responseData);
    20. } catch {
    21. e.printStackTrace()
    22. }
    23. }
    24. }).start();
    25. }
    26. ...
    27. }
  • 相关阅读:
    buuctf(探险3)
    [nlp] 主动学习
    API(3) StringBuffer类和StringBulider类
    17.重定向(redirect)和请求转发(forward)
    C语言函数strcmp比较字符串使用方法,scanf中空格输入小结。
    W5100S-EVB-PICO主动PING主机IP检测连通性(十)
    九零后程序员心塞:“30岁,月薪还没过万,是我的问题吗”
    0918 框架理论知识
    基于springboot的社区疫情管理系统源码
    智能座舱架构与芯片- (10) 音频篇 下
  • 原文地址:https://blog.csdn.net/XXX_17/article/details/126094244