1HttpURLConnection implementation scheme
When making a network request, the user needs to determine the permission of the request, and add the permission of the network request to the xml
<uses-permission android:name="android.permission.INTERNET"/>
Simple implementation of network requests
class HttpURLConnectionTest:AppCompatActivity() {<!-- --> override fun onCreate(savedInstanceState: Bundle?) {<!-- --> super.onCreate(savedInstanceState) setContentView(R.layout.internet_layout) //The first way to request the network HttpURLConnection get_date_by_url.setOnClickListener(){<!-- --> sendRequestWithHttpUrl() } } private fun sendRequestWithHttpUrl(){<!-- --> 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 //Specify the request method // connection.requestMethod="Post" //Network output, with parameter request //val output=DataOutputStream(connection. outputStream) //output.writeBytes("username=admin & amp;password=121231") //Network response input 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 {<!-- --> //Disconnect connection?. disconnect() } } } private fun showResponse(response:String){<!-- --> //This method can perform asynchronous UI interface update runOnUiThread {<!-- --> response_data.text=response } } }
2 Use OKHttp for network requests
First, you need to introduce the OkHttp dependency in the build.gradle file, and specify the version
//Join OKhttp implementation 'com.squareup.okhttp3:okhttp:4.9.0'
class HttpURLConnectionTest:AppCompatActivity() {<!-- --> override fun onCreate(savedInstanceState: Bundle?) {<!-- --> super.onCreate(savedInstanceState) setContentView(R.layout.internet_layout) get_date_by_okHttp.setOnClickListener(){<!-- --> sendRequestWithOkHttp() } } 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() } } } private fun showResponse(response:String){<!-- --> //This method can perform asynchronous UI interface update runOnUiThread {<!-- --> response_data.text=response } } }
Note that java.lang.ExceptionInInitializerError is reported if OkHttpClient is used. It may be a problem with the imported version of the OKhttp package, just download the appropriate version again.
A better way to write OKHttp in 3 actual scenarios
When there are relatively few requests, it is also possible to use OKHttp directly in the code, but if there are too many requests, it is impossible to put all the requests in the project code, so it is necessary to extract and abstract the request method into the tool class , to achieve a simpler call. And when performing sub-thread tasks, the result needs to be returned to the main thread, so it is necessary to use the callback interface for data update
Encapsulate HttpURLRequest tool class and OKHtttp tool class
A custom interface is required when using HttpURLRequest
interface HttpCallbackListener {<!-- --> fun onFinish(response: String) fun onError(e:Exception) }
Then encapsulate the method and call the callback interface in the tool class
object HttpUtil {<!-- --> fun sendHttpRequest(address:String,listener:HttpCallbackListener){<!-- --> thread {<!-- --> var connection:HttpURLConnection?=null try{<!-- --> val response = StringBuilder() val url=URL(address) 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) } } listener. onFinish(response. toString()) }catch (e:Exception){<!-- --> e. printStackTrace() listener.onError(e) }finally {<!-- --> connection?. disconnect() } } } //The method of using OkHttp fun sendOKHttpRequest(address:String,callback:okhttp3.Callback){<!-- --> val client=OkHttpClient() val request = Request. Builder() .url(address) .build() //The child thread has been opened inside the enqueue client.newCall(request).enqueue(callback) }
Instructions
class HttpURLConnectionTest:AppCompatActivity() {<!-- --> override fun onCreate(savedInstanceState: Bundle?) {<!-- --> super.onCreate(savedInstanceState) setContentView(R.layout.internet_layout) //Use the tool class to write logic get_date_by_util_Httpurl.setOnClickListener{<!-- --> HttpUtil.sendHttpRequest("https://www.baidu.com", object :HttpCallbackListener{<!-- --> override fun onFinish(response: String) {<!-- --> showResponse(response) } override fun onError(e: Exception) {<!-- --> println("Exception handling here") } }) } get_date_by_util_okHttp.setOnClickListener(){<!-- --> HttpUtil.sendOKHttpRequest("https://www.baidu.com", object:Callback{<!-- --> override fun onFailure(call: Call, e: IOException) {<!-- --> println("If it fails, print exception handling") } override fun onResponse(call: Call, response: Response) {<!-- --> val responseData = response.body?.string() if (responseData != null) {<!-- --> showResponse(responseData) } } }) } } private fun showResponse(response:String){<!-- --> //This method can perform asynchronous UI interface update runOnUiThread {<!-- --> response_data.text=response } } }
4 more powerful Retrofit framework
Retrofit is a comprehensive framework based on OKHttp, with better data request specifications and response specifications
1 Create an entity class for the purpose of using GSON to map the returned object
class Student(val id:Int,val name:String,val className:String) {<!-- --> }
2 Create a Service interface to handle the return of different request paths
interface StudentService {<!-- --> //The specific resource address under the website is specified here @GET("gete.json") fun getStudentInfo(): Call<List<Student>> }
3 Use Retrofit and process the returned data
use_Retrofit.setOnClickListener(){<!-- --> val retrofit = Retrofit. Builder() //It will be combined with the address in the Service to determine a unique request address .baseUrl("base address") .addConverterFactory(GsonConverterFactory.create()) .build() val studentService = retrofit.create(StudentService::class.java) studentService.getStudentInfo().enqueue(object:retrofit2.Callback<List<Student>>{<!-- --> override fun onResponse( call: retrofit2. Call<List<Student>>, response: retrofit2.Response<List<Student>> ) {<!-- --> val students = response. body() if(students!=null){<!-- --> for(student in students){<!-- --> println("Output student information ${<!-- -->student.id}, etc.") } } } //handle the exception override fun onFailure(call: retrofit2.Call<List<Student>>, t: Throwable) {<!-- --> t. printStackTrace() } }) }
4 Solutions for some other request situations
interface StudentService {<!-- --> //The specific resource address under the website is specified here @GET("/user/Student/getStudent.json") fun getStudentInfo(): Call<List<Student>> / / Handle the situation with variable parameters in the path, keyword Path @GET("{page}/getStudent.json") fun getStudentInfoByPage(@Path("page") page:Int): Call<List<Student>> //Keyword Query with parameters in the path when processing the Get request @GET("/user/Student/getStudent.json") fun getStudentInfoByNameAndClassName(@Query("name") name:String,@Query("calssName") className:String):Call<List<Student>> //Delete a student according to id, if you don't care about the return value, use Call<ResponseBody> instead @DELETE("/user/Student/{id}") fun deleteById(@Path("id") id:Int):Call<ResponseBody> //If you want to submit data, submit directly according to the object @POST("user/Student") fun createStudent(@Body student:Student): Call<ResponseBody> //If you want to add request parameters to the request header, fill the data in the form of key-value pairs Static method @Headers("User-Agent:okHttp", "Cache-Control:max-age=0") @GET("address") fun getStudentBy(): Call<Student> //dynamic @GET("address 2") fun getStudentByDynamic( @Header("User-Agent") userAgent: String, @Header("Cache-Control") cache_control: String): Call<Student> } }
The creation process is too complicated when using Retrofit, so it is tooled
Processing in tool stack
object ServiceCreator {<!-- --> private const val BASE_URL="your own base access address" private val retrofit = Retrofit. Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build() //Only provide one method to return the created Service instance externally fun <T> create(serviceClass: Class<T>):T= retrofit. create(serviceClass) }
Instructions
use_Retrofit.setOnClickListener(){<!-- --> /*val retrofit=Retrofit. Builder() .baseUrl("base address") .addConverterFactory(GsonConverterFactory.create()) .build()*/ val studentService = ServiceCreator.create(StudentService::class.java) studentService.getStudentInfo().enqueue(object:retrofit2.Callback<List<Student>>{<!-- --> override fun onResponse( call: retrofit2. Call<List<Student>>, response: retrofit2.Response<List<Student>> ) {<!-- --> val students = response. body() if(students!=null){<!-- --> for(student in students){<!-- --> println("Output student information ${<!-- -->student.id}, etc.") } } } //handle the exception override fun onFailure(call: retrofit2.Call<List<Student>>, t: Throwable) {<!-- --> t. printStackTrace() } }) }