0%

在安卓平台建立 HTTP 连接-1

前言

最近需要写一款与服务器进行交互的 App,搜索了一下发现主要都是使用 HTTP 而不是之前学编程语言时用的 Socket。

Android 环境下的 HTTP 库目前做的最好的有 2 个:Volley 和 OKHTTP,这两个直到现在都还在维护。

试了一下 OkHttp 的 demo 如果直接扔进安卓项目会提示经典的报错:主线程不能做网络操作。由于我连创建线程的代码都懒的搞,所以这里就用 Volley 了。(最后跑通发现,Volley也要自己新开线程,还以为亲儿子有黑科技的)

正文

上来直接新建项目,然后把安卓文档的代码扔进去,把 URL 改成百度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val textView = findViewById<TextView>(R.id.text)

// Instantiate the RequestQueue.
val queue = Volley.newRequestQueue(this)
val url = "http://baidu.com"

// Request a string response from the provided URL.
val stringRequest = StringRequest(
Request.Method.GET, url,
Response.Listener<String> { response ->
// Display the first 500 characters of the response string.
textView.text = "Response is: ${response.substring(0, 500)}"
},
Response.ErrorListener {
println(it.toString())
textView.text = "That didn't work!\n" + it.toString() })

// Add the request to the RequestQueue.
queue.add(stringRequest)

}
}

运行后却报错, That didn’t work! 然后把报错信息打印了一下,发现是 java.io.IOException: Cleartext HTTP traffic to baidu.com not permitted

不让明文传输?意思强行 HTTPS ?搜了一下解决方案: https://blog.csdn.net/nidongde521/article/details/86496804

改一下 Manifest: 加上 android:usesCleartextTraffic="true"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

继续报错。com.android.volley.NoConnectionError: java.net.UnknownHostException: Unable to resolve host "baidu.com": No address associated with hostname,后来发现就是权限声明的 typo…… 改一下就没问题了。

另外从 Android studio 的虚拟机访问宿主机的 IP 地址是 10.0.2.2 。可以进 WIFI设置里查看默认网关,这个网关其实就是宿主机。

最后的代码贴到这里:记得manifest改权限,gradle 加 volley 的 dependency。这些在 Volley 的文档都有。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package cn.haulyn5.httpdemo

import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.android.volley.Request
import com.android.volley.Response
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley


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

val tmpRunnable = Runnable {
run {
val textView = findViewById<TextView>(R.id.text)

// Instantiate the RequestQueue.
val queue = Volley.newRequestQueue(this)
val url = "http://baidu.com"

// Request a string response from the provided URL.
val stringRequest = StringRequest(
Request.Method.GET, url,
Response.Listener<String> { response ->
// Display the first 500 characters of the response string.
if(response.toString().length < 500)
textView.text = "Response is: ${response}"
else
textView.text = "Response is: ${response.substring(0, 500)}"
},
Response.ErrorListener {
println(it.toString())
textView.text = "That didn't work!\n" + it.toString() })

// Add the request to the RequestQueue.
queue.add(stringRequest)
}
}

Thread(tmpRunnable).start()

}
}

附上开启新活动的代码,方便以后 copy。

1
2
val intent = Intent(this, GetActivity::class.java)
startActivity(intent)