Android网络技术——HttpUrlConnection和OkHttp

Android网络技术——HttpUrlConnection和OkHttp


  • HttpURLConnection是一个abstract类,可用于发起网络请求
  • OkHttp不仅在接口封装上做得简单易用,就连在底层实现上也是自成一派,比起原生的HttpURLConnection,可以说是有过之而无不及,现在已经成了广大Android开发者首选的网络通信库

一、布局设置


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:layout_marginBottom="10dp">
        <EditText
            android:id="@+id/url"
            android:layout_weight="7"
            android:hint="请输入网址"
            android:inputType="text"
            android:layout_width="0dp"
            android:layout_height="wrap_content" />
        <View
            android:layout_width="0dp"
            android:layout_weight="0.5"
            android:layout_height="match_parent" />
        <Button
            android:id="@+id/jumpToWeb"
            android:layout_weight="2.5"
            android:layout_width="0dp"
            android:text="跳转"
            android:layout_height="wrap_content" />
    LinearLayout>

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

LinearLayout>

注:ScrollView容器用于滚动内部的组件,并且只允许有一个child

二、网络请求

2.1 HttpURLConnection

步骤如下:

  1. 创建URL对象
val url = URL(urlStr.text.toString())
  1. 使用HttpURLConnection类打开到该URL的连接
val connection:HttpURLConnection = url.openConnection() as HttpURLConnection
  1. HttpURLConnection实例属性设置
connection.requestMethod = "GET"
connection.connectTimeout = 8000
connection.readTimeout = 8000
  1. 获得请求后服务器返回的数据流
val inputText = connection.inputStream
  1. 对获取到的输入流进行读取
val reader = BufferedReader(InputStreamReader(inputText))
reader.use {
    it.forEachLine {
        response.append(it)
    }
}

注:这里的use会让reader在使用完后自动关闭

2.2 OkHttp

  1. 在项目app/build.gradle文件中添加OkHttp库的依赖
dependencies {
 	implementation 'com.squareup.okhttp3:okhttp:4.1.0'
}
  1. 创建OkHttpClient实例
val client = OkHttpClient()
  1. 如果要发起http请求,则需要创建一个Request对象
val request = Request.Builder()
				     .url(urlStr.text.toString())
				     .build()
  1. 创建一个Call对象,传入request参数,并调用它的execute方法来发送请求以获得服务器返回的数据
val response = client.newCall(request).execute()
  1. 获得response的主体内容
val responseData = response.body?.string()
if(responseData != null) {
	  showResponseTextOnUI(responseData)
}

三、完整代码

3.1 HttpURLConnection

class MainActivity : AppCompatActivity() {
    private lateinit var urlStr: TextView
    private lateinit var jumpToWeb: Button
    private lateinit var responseText: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        urlStr = findViewById(R.id.url)
        jumpToWeb = findViewById(R.id.jumpToWeb)
        responseText = findViewById(R.id.responseText)

        jumpToWeb.setOnClickListener {
            sendRequestWithHttpURLConnection(urlStr)
        }
    }

    private fun sendRequestWithHttpURLConnection(urlStr: TextView) {
        // 需要开启线程发起网络请求,因为网络请求耗时很大
        thread {
            var connection: HttpURLConnection? = null
            try {
                val response = StringBuilder()
                // 1. 创建URL对象
                val url = URL(urlStr.text.toString())
                // 2. 使用HttpURLConnection类打开到该URL的连接
                connection = url.openConnection() as HttpURLConnection
                // 3. HttpURLConnection实例属性设置
                connection.requestMethod = "GET"
                connection.connectTimeout = 8000
                connection.readTimeout = 8000
                // 4. 获得请求后服务器返回的数据流
                val inputText = connection.inputStream
                // 5. 对获取到的输入流进行读取
                val reader = BufferedReader(InputStreamReader(inputText))
                reader.use {
                    it.forEachLine {
                        response.append(it)
                    }
                }
                // 在主线程UI中显示
                showResponseTextOnUI(response.toString())
            } catch (e: Exception) {
                e.printStackTrace()
            } finally {
                connection?.disconnect()
            }
        }
    }

    private fun showResponseTextOnUI(responseStr: String) {
        // 在主线程上才能操作UI,将结果显示到界面上
        runOnUiThread {
            responseText.text = responseStr
        }
    }
}

3.2 OkHttp

// OkHttp
private fun sendRequestWithOkHttp(urlStr: TextView) {
    // 需要开启线程发起网络请求,因为网络请求耗时很大
    thread {
        try {
            // 1. 创建OkHttpClient实例
            val client = OkHttpClient()
            // 2. 如果要发起http请求,则需要创建一个Request对象
            val request = Request.Builder()
                .url(urlStr.text.toString())
                .build()
            // 3. 创建一个Call对象,传入request参数,并调用它的execute方法来发送请求以获得服务器返回的数据
            val response = client.newCall(request).execute()
            // 4. 获得response的主体内容
            val responseData = response.body?.string()
            if(responseData != null) {
                showResponseTextOnUI(responseData)
            }
        } catch (e:Exception) {
            e.printStackTrace()
        }
    }
}

注:

  • 网络请求是一个比较耗时的操作,所以一般需要另开一个线程异步执行
  • 对UI的操作需要在主线程中进行,可以使用runOnUiThread

四、权限申请

由于本程序使用到了网络功能,而访问网络是需要声明权限的,因此我们还得修改AndroidManifest.xml文件,并加入权限声明

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

五、运行结果

Android网络技术——HttpUrlConnection和OkHttp_第1张图片

你可能感兴趣的:(Android,第一行代码,android)