关于使用kotlin简单使用retrofit2
1.创建Retrofit实例
object ServiceCreator {
private const val BASE_URL = "http://218.7.112.123:10001/"
//const val 可见性为public final static,可以直接访问 val 可见性为private final static
private val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
fun <T> create (serviceClass: Class<T>) : T = retrofit.create(serviceClass) //外部可见的create()
}
接口地址
class ApiUrl{
companion object{
/**
* kotlin通过引入“伴生对象”的概念来替代java里的静态变量及方法
* 下面是定义伴生对象的代码:
* class StaticTest {
companion object{//伴生对象是可以指定名字的,不过一般都省略掉。
var STATIC_VAR = 0
fun staticMethod(str: String?) {
println(str)
}
}
}
*/
//登录
const val LOGIN_URL = "/prod-api/api/login"
//全部服务
const val ALL_SERVICE = "/prod-api/api/service/list"
//TOKEN
var TOKEN = ""
}
}
根据API创建数据类(接收服务器返回数据类)
登录请求类
data class LoginRequest(
val password: String,
val username: String
)
登录返回数据类
data class LoginResponse(
val code: Int,
val msg: String,
val token: String
)
全部服务的数据类
data class AllService(
val code: Int,
val msg: String,
val rows: List<ServiceDetail>,
val total: Int
)
data class ServiceDetail(
val createBy: Any,
val createTime: String,
val id: Int,
val imgUrl: String,
val isRecommend: String,
val link: String,
val params: Params,
val pid: Int,
val remark: Any,
val searchValue: Any,
val serviceDesc: String,
val serviceName: String,
val serviceType: String,
val sort: Int,
val updateBy: Any,
val updateTime: String
)
class Params
创建网络请求接口
interface ApiService {
//post请求 请求数据类型:application/json
@POST(ApiUrl.LOGIN_URL)
@Headers("Content-Type: application/json", "Accept: application/json") //需要添加头
fun login(@Body RequestBody: RequestBody) : Call<LoginResponse>
//get请求
@GET(ApiUrl.ALL_SERVICE)
@Headers("Content-Type: application/x-www-form-urlencoded")
fun getAllService() : Call<AllService>
}
具体使用
登录
activity_login.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".LoginActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="@id/et_login_account"
android:text="账号:"
android:id="@+id/tv_login_account"
tools:ignore="MissingConstraints" />
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/et_login_account"
app:layout_constraintStart_toEndOf="@id/tv_login_account"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:inputType="text"
android:hint="请输入账号"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/et_login_account"
app:layout_constraintBottom_toBottomOf="@id/et_login_pwd"
android:id="@+id/tv_login_pwd"
android:text="密码:"
tools:ignore="MissingConstraints" />
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/et_login_pwd"
app:layout_constraintTop_toBottomOf="@id/et_login_account"
app:layout_constraintStart_toEndOf="@id/tv_login_pwd"
app:layout_constraintEnd_toEndOf="parent"
android:inputType="textPassword"
android:hint="请输入密码"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_login"
app:layout_constraintTop_toBottomOf="@id/et_login_pwd"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:text="登录"/>
</androidx.constraintlayout.widget.ConstraintLayout>
LoginActivity
class LoginActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
//按钮点击事件
btn_login.setOnClickListener { view ->
val account = et_login_account.text.trim().toString()
val pwd = et_login_pwd.text.trim().toString()
//发送application/json数据类型
val loginRequest = LoginRequest(pwd, account)
val json = FormBody.create(
MediaType.parse("application/json; charset=utf-8"),
Gson().toJson(loginRequest)
)
val apiService = ServiceCreator.create(ApiService::class.java)
val loginService = apiService.login(json)
//发送网络请求 异步
loginService.enqueue(object : Callback<LoginResponse>{
override fun onFailure(p0: Call<LoginResponse>, p1: Throwable) {
}
override fun onResponse(p0: Call<LoginResponse>, p1: Response<LoginResponse>) {
Log.d("TAGCODE",p1.body()?.token.toString())
if (p1.body()?.code == 200){
ApiUrl.TOKEN = p1.body()?.token.toString()
//一个activity离开后,按返回键不要再回去.那么我们需要把这个activity从栈区中去除
val intent = Intent()
intent.flags =
Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
intent.setClass(this@LoginActivity, MainActivity::class.java)
startActivity(intent)
}else{
Toast.makeText(this@LoginActivity,p1.body()?.msg,Toast.LENGTH_SHORT).show()
et_login_pwd.text = null
et_login_account.text = null
}
}
})
}
}
}
全部服务
MainActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
getData()
}
private fun getData() {
val apiService = ServiceCreator.create(ApiService::class.java)
val allServiceCall = apiService.getAllService()
allServiceCall.enqueue(object : Callback<AllService>{
override fun onFailure(p0: Call<AllService>, p1: Throwable) {
}
override fun onResponse(p0: Call<AllService>, p1: Response<AllService>) {
}
})
}
}
最后
别忘记
<uses-permission android:name="android.permission.INTERNET"/>
Android12必须在activity中加入
android:exported="true"
Android9 http问题,在application加入
android:usesCleartextTraffic="true"