将介绍Android上的网络编程。包括HttpURLConnection及Volley、OKHttp、Retrofit框架。(HttpClient由于被淘汰,不予以介绍)
- HttpURLConnection的使用
使用GET方法。注意在AndroidMainifest.xml中加入使用网络的权限。
<uses-permission android:name="android.permission.INTERNET"/>
使用方法如下:
fun get():String{
var message:String = ""
try{
val url:URL = URL("https://www.baidu.com")
val connection:HttpURLConnection = url.openConnection() as HttpURLConnection
connection.requestMethod = "GET"
connection.connectTimeout = 5000
connection.connect()
val inputStream:InputStream = connection.inputStream
var data:ByteArray = ByteArray(1024)
var sb:StringBuilder = StringBuilder()
var length:Int = inputStream.read(data)
while (length != -1){
var s:String = String(data, Charset.forName("utf-8"))
sb.append(s)
length = inputStream.read(data)
}
message = sb.toString()
inputStream.close()
connection.disconnect()
}catch (e:IOException){
e.printStackTrace()
}
return message
}
输出为网页代码,过长不展示。
Post使用需要加入这些关键代码:
connection.requestMethod = "POST"
connection.doOutput = true
connection.doInput = true
connection.useCaches = false
connection.connectTimeout = 30000
connection.setRequestProperty("Content-type", "application/x-javascript->json")
connection.connect()
val outputStream: OutputStream = connection.outputStream
outputStream.write(param.toByteArray())//param格式:属性=xxx&属性1=xxxx
- Volley
依赖导入:
compile group: 'com.android.volley', name: 'volley', version: '1.1.1'
Volley是一个通信框架,为了简化之前的方法,同时提升效率和安全。用法如下:
/**
* volley
*/
private fun volley_get(){
val mQueue:RequestQueue = Volley.newRequestQueue(applicationContext)
val mStringRequest:StringRequest = StringRequest(Request.Method.GET, "https://www.baidu.com", Response.Listener {
println(it)
}, Response.ErrorListener {
println("Error:$it")
})
mQueue.add(mStringRequest)
}
/**
* volley post
*/
private fun volley_post(){
val mQueue:RequestQueue = Volley.newRequestQueue(applicationContext)
val mJsonObjectRequest:JsonObjectRequest = JsonObjectRequest("https://ip.taobao.com/service/getInfo.php?ip=59.108.54.37",null,
Response.Listener<JSONObject> {
println(it.toString())
}, Response.ErrorListener {
println("Error$it")
})
//JsonObjectRequest(Request.Method.Post, Url, JsonParams,Listener(), ErrorListener())
mQueue.add(mJsonObjectRequest)
}
没有后台好烦。另外,还有ImageRequest、ImageLoader、NetworkImageView、NetworkImageView。
3. OKHttp
OKHttp比较好用吧。很OK
依赖导入:
compile group: 'com.squareup.okhttp3', name: 'okhttp', version: '4.10.0-RC1'
compile group: 'com.squareup.okio', name: 'okio', version: '2.9.0'
- 首先,使用GET,如果你和我一样懒的话,在一个文件中测试,如果找不到Request.Builder,记得更换导入的 Request,可能使用的是上一个Volley的。
rivate fun get(){
val requestBuilder: Request.Builder = Request.Builder().url("https://www.baidu.com")
requestBuilder.method("GET", null)
val request:Request = requestBuilder.build()
val mOkHttpClient:OkHttpClient = OkHttpClient()
val mCall: Call = mOkHttpClient.newCall(request)
mCall.enqueue(object:Callback{
override fun onFailure(call: Call, e: IOException) {
}
override fun onResponse(call: Call, response: okhttp3.Response) {
println(response.body!!.string())
}
})
}
- 然后,是Post。
private fun post(){
val formBody:RequestBody = FormBody.Builder()
.add("ip", "59.108.54.37")
.build()
val request:Request = Request.Builder()
.url("https://ip.taobao.com/service/getInfo.php")
.post(formBody)
.build()
val mOkHttpClient:OkHttpClient = OkHttpClient()
val call:Call = mOkHttpClient.newCall(request)
call.enqueue(object :Callback{
override fun onResponse(call: Call, response: okhttp3.Response) {
println(response.body!!.string())
}
override fun onFailure(call: Call, e: IOException) {
println("ERROR!")
}
})
}
设置超时等。
mOkHttpClient.newBuilder()
.connectTimeout(15, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECOND)
- Retrofit的使用
它是由Square公司开发的一款针对Android网络请求的框架,底层基于OKHttp实现。运行时采用注解的方式提供功能,是它的特点。
依赖导入:
compile group: 'com.squareup.retrofit2', name: 'retrofit', version: '2.9.0'
compile group: 'com.squareup.retrofit2', name: 'converter-gson', version: '2.9.0'
Retrofit的注解分为三类:HTTP请求方法注解、标记类注解和参数类注解。HTTP注解有8种:GET、POST、PUT、DELETE、HEAD、PATCH、OPTIONS和HTTP。HTTP可以替换前7种,也可以扩展请求方法。标记类注解有3种,它们是FormUrlEncoded、Multipart、Streaming。参数类注解有Header、Headers、Body、Path、Field、FieldMap、Part、PartMap、Query、QueryMap。
- @GET使用:
data class IpModel(var country:String){}
public interface IPservice{
@GET("getIpInfo.php?ip=59.108.54.37")
fun getIp():Call<IpModel>
}
private fun get(){
val url:String = "https://ip.taobao.com/service/"
val retrofit:Retrofit = Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build()
val ipService:IPservice = retrofit.create(IPservice::class.java)
val call:Call<IpModel> = ipService.getIp()
call.enqueue(object : Callback<IpModel> {
override fun onResponse(call: Call<IpModel>, response: retrofit2.Response<IpModel>) {
println(response.body()!!.country)
}
override fun onFailure(call: Call<IpModel>, t: Throwable) {
}
})
}
- @Path使用,可以将Path替换为具体网址
public interface IpServiceForPath{
@GET("{path}/getIpInfo.php?ip=59.108.54.37")
fun getIpMsg(@Path("path") path:String):Call<IpModel>
}
- 另外,还有@Query
public interface IpServiceForQuery{
@GET("getIpInfo.php")
fun getIpMsg(@Query("ip") ip:String):Call<IpModel>
}
- @QueryMap
public interface IpServiceForQuery{
@GET("getIpInfo.php")
fun getIpMsg(@QueryMap options:Map<String, String>):Call<IpModel>
}
- 下面是POST的注释
- @Field使用键值对方式
public interface IpServiceForQuery{
@FormUrlEncoded
@POST("getIpInfo.php")
fun getIpMsg(@Field("ip") first:String):Call<IpModel>
}
- @Body发送Json格式的数据
public interface IpServiceForQuery{
@POST("getIpInfo.php")
fun getIpMsg(@Body ip:Ip):Call<IpModel>
}
data class Ip(private var ip:String){}
- @Part单个文件上传
public interface IpServiceForPart{
@Multipart
@POST("user/photo")
fun updateUser(@Part photo:MultipartBody.Part, @Part("description") description:RequestBody):Call<IpModel>
}
- @PartMap多个文件上传
- @Headers添加消息报头