前言 最近需要写一款与服务器进行交互的 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) val queue = Volley.newRequestQueue(this ) val url = "http://baidu.com" val stringRequest = StringRequest( Request.Method.GET, url, Response.Listener<String> { response -> textView.text = "Response is: ${response.substring(0 , 500 )} " }, Response.ErrorListener { println(it.toString()) textView.text = "That didn't work!\n" + it.toString() }) 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.httpdemoimport android.os.Bundleimport android.widget.TextViewimport androidx.appcompat.app.AppCompatActivityimport com.android.volley.Requestimport com.android.volley.Responseimport com.android.volley.toolbox.StringRequestimport com.android.volley.toolbox.Volleyclass 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) val queue = Volley.newRequestQueue(this ) val url = "http://baidu.com" val stringRequest = StringRequest( Request.Method.GET, url, Response.Listener<String> { response -> 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() }) queue.add(stringRequest) } } Thread(tmpRunnable).start() } }
附上开启新活动的代码,方便以后 copy。
1 2 val intent = Intent(this , GetActivity::class .java)startActivity(intent)