WebView以及使用HTTP访问访问网络

使用网络技术

  • 在Android开发当中,我们应该合理的使用网络编写出更加出色的应用程序,下面学习以下如何在手机端使用HTTP和服务器进行网络交互,并对服务器返回的数据进行解析,这也是在Android当中最常用到的网络技术

WebView的用法

  • 在开发的过程中有时候我们会遇到一些比较特殊的需求,比如说是要在应用程序当中展示一些网页,但是通常来说加载和显示到网页是浏览器应该做的事情,但是在需求当中又不允许我们打开浏览器,我们不可能自己去写一个浏览器出来,这时候应该怎么办呢?
  • 其实Android早就考虑到了这种特殊的需求,给开发人员提供了一个WebView控件,借助这个控件我们就可以在自己的应用程序当中嵌入一个浏览器,从而轻松的展示各种各样的网页.
  • 下面新建一个WebViewTest项目来使用一下这个控件的使用
  • 修改activity_main.xml文件当中的代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <WebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>
  • 可以看到在该文件当中只包含了一个WebView控件,这个空间就是用来显示网页的,这里的写法也比较简单,给它设置了一个id,然后让他充满了整个屏幕
  • 然后修改MainActivity当中的代码
class MainActivity : AppCompatActivity() {
    @SuppressLint("SetJavaScriptEnabled")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        webView.settings.javaScriptEnabled = true
        webView.webViewClient = WebViewClient()
        webView.loadUrl("https://www.baidu.com")
    }
}
  • 上述代码也比较简单,通过WebView的getSettings()方法可以设置一些浏览器的属性,在这里调用了setJavaScriptEnabled()方法,让WebView支持JavaScript脚本
  • 接下来是比较重要的部分,调用了WebView的setWebViewClient()方法并且传入了一个WebViewClient()的实例,这段代码的作用是,当需要从一个网页跳转到另外一个网页的时候,我们希望目标网页仍然在当前WebView当中进行显示,而不是打开系统浏览器.
  • 最后一步就是调用了WebView的loadUrl()方法,并将网址传入,即可展示相应的网页内容
  • 另外需要注意的是,由于本程序使用了网络功能,需要在AndroidManifest.xml文件当中,加入网络权限声明
<uses-permission android:name="android.permission.INTERNET" />
  • 然后运行程序就可以看到我们打开了百度的网页

.

使用HTTP访问网络

  • HTTP协议的基本原理简单来说就是,客户端向服务器发送一条HTTP请求,服务器在收到请求之后会返回一些数据给客户端,然后客户端再对这些数据进行解析和处理就可以了,一个浏览器的基本原理其实也就是这样.
  • 在上述代码的WebView控件当中就是向百度的服务器发送了一条HTTP请求,接着服务器分析出我们想要访问的是百度的首页,接着把网页的HTML代码进行返回,然后WebView再调用手机浏览器内核对返回的HTML代码进行解析,最终将网页展示出来.
  • 简单来说,WebView已经在后台帮我们处理好了发送HTTP请求,接收服务器响应,解析返回的数据,以及最终的页面展示这几个步骤.

使用HttpURLConnection

  • 在过去Android发送HTTP请求的方式一般有两种:HttpURLConnection和HttpClient两种方式
  • 但是HttpClient存在API数量过多,扩展困难等问题,所以在Android6.0系统中HttpClient的功能被完全移除了
  • 下面看看官方推荐的HttpURLConnection的用法
  • 首先需要获取HttpURLConnection实例,一般只需要创建一个URL对象,并传入目标的网络地址,然后调用一下openConnection()方法即可,如下所示
val url = URL("Https://www.baidu.com")
val connection = url.openConnection() as HttpURLConnection
  • 在得到HttpURLConnection的实例之后,我们可以设置一下HTTP请求所使用的方法,常用的方法主要有:POST,GET
  • POST一般表示希望提交数据给服务器,GET一般表示从服务器获取数据
  • 写法如下:
connection.requestMethod = "GET"
  • 接下来可以进行一些自由的定制,比如设置连接超时,读取超时的毫秒数,以及服务器希望得到的一些消息头.这部分内容根据自己的实际情况进行编写,示例写法如下:
connection.connectTimeout = 8000
connection.readTimeout = 8000
  • 之后再调用getInputstream()方法就可以获取到服务器返回的输入流了,剩下的任务就是对输入流进行读取:
val input = connection.inputStream
  • 最后可以调用disconnect()方法,将这个HTTP连接进行关闭
connection.disconnect()
  • 下面新建一个NetworkTest项目,来体验一下HttpURLConnection的用法
  • 首先修改activity_main.xml文件中的代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/sendRequestBtn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Send Request" />

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/respondText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </ScrollView>


</LinearLayout>
  • 在这里面我们主要使用了一个新的控件ScrollView,因为由于手机屏幕比较小,有时候过多的内容显示不下,借助ScrollView控件就可以通过滚动屏幕的方式来查看屏幕以外的内容了

  • 另外还有一个按钮和一个TextView,分别用来发送HTTP请球和显示服务器返回的数据的

  • 现在写MainActivity当中的代码来编写具体的逻辑

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        sendRequestBtn.setOnClickListener {
            sendRequestWithHttpURLConnection()
        }
    }

    private fun sendRequestWithHttpURLConnection() {
        //开启线程发起网络请求
        thread {
            var connection: HttpURLConnection? = null
            try {
                val response = StringBuilder()
                val url = URL("https://www.baidu.com")
                connection = url.openConnection() as HttpURLConnection
                connection.connectTimeout = 8000
                connection.readTimeout = 8000
                val input = connection.inputStream
                //下面对获取到的输入流进行读取
                val reader = BufferedReader(InputStreamReader(input))
                reader.use {
                    reader.forEachLine {
                        response.append(it)
                    }
                }
                showResponse(response.toString())
            } catch (e: Exception) {
                e.printStackTrace()
            } finally {
                connection?.disconnect()
            }
        }
    }

    private fun showResponse(response: String) {
        runOnUiThread {
            //在这里进行UI操作,将结果显示到界面上
            respondText.text = response
        }
    }
}
  • 在sendRequestWithHttpURLConnection()方法中,先开启了一个子线程,然后在这个子线程中先使用HttpURLConnection发出了一条HTTP请求,然后利用BufferReader对服务器返回的流进行读取,并将结果传入到showResponse()方法当中
  • 而在showResponse()方法中,调用了runOnUiThread()方法,之所以调用这个方法是因为,Android是不允许在子线程当中更新UI的,而这个方法是利用了异步消息处理机制,所以借助这个方法我们将服务器返回的数据更新到界面上
  • 最后还要再声明一下网络权限
<uses-permissi android:name="android.permission.INTERNET" />
  • 现在运行程序点击按钮就可以看到下面的这些数据

.

  • 可以看到服务器给我们返回的就是这种HTML代码,只不过浏览器可以将这些HTML代码解析渲染成为精美的网页
  • 上述是从服务器获取数据,加假如我们想要向服务器提交数据该怎么办?
  • 这时候我们可以使用POST方法,并在获取输入流之前将要提交的数据进行写出即可
  • 每条数据都要以键值对的形式存在,数据与数据之间使用"&"符号进行隔开,比如我们想要向服务器提交用户名和密码,我们可以这样写
connection.requestMethod = "POST"
val output = DataOutputStream(connection.outputStream)
output.writeBytes("username=admin&password=123456")

使用OkHttp

  • 在开源盛行的今天,除过HttpURLConnection,也并不是没有其他的选择,有许多出色的网络通信库都可以替代原生的HttpURLConnection,而OkHttp无疑是做的最出色的一个

  • OkHttp是Square公司开发的一款在接口封装上做的简单易用,就连底层也是自成一派,现在已经成为广大Android开发者首选的网络通信库

  • OkHttp的项目主页地址是:Http://github.com/square/okhttp

  • 在使用OkHttp之前我们需要现在项目当中添加OkHttp库的依赖

implementation("com.squareup.okhttp3:okhttp:4.10.0")

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yrwg3Y0d-1672297573695)(C:/Users/zhengbo/%E6%88%91%E7%9A%84%E5%AD%A6%E4%B9%A0/Typora%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/%E5%AE%89%E5%8D%93/image-20221225212110621.png)]

  • 添加上述依赖之后会自动下载两个库,一个是OkHttp库,一个Okio库,后者是前者的通信基础.
  • 使用OkHttp首先需要创建一个OkHttpClient实例,如下所示
val client = OkHttpClient()
  • 接下来如果想要发起一条HTTP请球,就需要创建一个Request对象:
val request = Request.Builder().build()
  • 上述代码是创建一了一个空的request对象,沃恩可以在最终的build()方法之前连缀很多个其他的方法来丰富这个Request对象,比如可以通过url()方法来设置目标网络地址,如下所示
val request = Request.Builder()
	.url("https://www.baidu.com")
	.build()
  • 之后调用OkHttpClient的newCall()方法来创建一个Call对象,并调用它的execute()方法,来发送请求并获取服务器返回的数据,写法如下:
val response = client.newCall(resquest).execute()
  • Response对象就是服务器返回的数据了,我们可以使用以下写法来的到返回的具体内容
val responseData = response.body?.string()
  • 如果我们要发起一条POST请求,会比GET请求稍微复杂一点,我们需要先构建Request Body对象来存放待提交的参数,如下所示:
val requestBody = FormBody.Builder()
	.add("username", "admin")
	.add("password", "123456")
	.build()
  • 然后在Request.Builder中调用一下post()方法,并将RequestBody对象传入
val request = Request.Builder()
	.url("https://www.baidu.com")
	.post(requestBody)
	.build()
  • 接下来的操作就和GET请求一样了.调用execute()方法来发送请求并获取服务器返回的数据即可
  • 在NetworkTest项目当中改用OkHttp的方式实现一遍
    private fun sendRequestWithOkHttp() {
        thread {
            try {
                val client = OkHttpClient()
                val request = Request.Builder()
                    .url("https://www.baidu.com")
                    .build()
                val response = client.newCall(request).execute()
                val responseData = response.body?.string()
                if (responseData != null) {
                    showResponse(responseData)
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
  • 该方法实现的效果和之前编写的sendRequestWithHttpURLConnection()方法实现的效果是一样的,但是在使用上还是简便了一些的.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值