如何在 Kotlin 中发出 API 请求?
Posted
技术标签:
【中文标题】如何在 Kotlin 中发出 API 请求?【英文标题】:How to make an API request in Kotlin? 【发布时间】:2017-12-26 10:14:01 【问题描述】:总的来说,我对 Kotlin 和 API 非常陌生,找不到使用这种语言创建 API 请求的语法。我正在创建网站的移动版本,因此我正在使用 android Studio 为已经建立的后端创建新的 UI。创建请求的步骤和语法是什么?任何帮助都深表感谢。
【问题讨论】:
查看这篇文章:codeflex.co/simple-restful-service-with-kotlin-and-spring-boot 【参考方案1】:拥有set your Android Studio to use Kotlin 后,进行 REST 调用非常简单,并且与 Java 的逻辑几乎相同。
这是一个使用OkHttp 的 REST 调用示例:
build.gradle
dependencies
//...
implementation 'com.squareup.okhttp3:okhttp:3.8.1'
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
MainActivity.kt
class MainActivity : AppCompatActivity()
private val client = OkHttpClient()
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
run("https://api.github.com/users/Evin1-/repos")
fun run(url: String)
val request = Request.Builder()
.url(url)
.build()
client.newCall(request).enqueue(object : Callback
override fun onFailure(call: Call, e: IOException)
override fun onResponse(call: Call, response: Response) = println(response.body()?.string())
)
以下是其他库的一些更复杂的示例:
Network request in Kotlin with Retrofit Network request in Kotlin with Retrofit and coroutines Network request in Kotlin with Dagger, RxJava, Retrofit in MVP【讨论】:
非常感谢您的详细回复。这肯定会帮助我取得一些进步。 任何从 onResponse 更新 UI 的尝试都会导致异常。最好改用 Retrofit。【参考方案2】:我已经使用改造 2 创建了一个示例 API 调用。首先,将这些库添加到 gradle 中
implementation "com.squareup.retrofit2:retrofit:2.3.0"
implementation "com.squareup.retrofit2:adapter-rxjava2:2.3.0"
implementation "com.squareup.retrofit2:converter-gson:2.3.0"
implementation "io.reactivex.rxjava2:rxandroid:2.0.1"
然后创建一个类来配置 Retrofit 2,比如 Connect.kt
class Connect
companion object
private fun getRetrofit(Url:String):Retrofit
return Retrofit.Builder()
.addCallAdapterFactory(
RxJava2CallAdapterFactory.create())
.addConverterFactory(
GsonConverterFactory.create())
.baseUrl(Url)
.build()
fun getApiData():Retrofit
val retrofitApi = getRetrofit(Url.BASE_URL)
return retrofitApi
fun callApi():CallApi
val retrofitCall = getApiData()
return retrofitCall.create(CallApi::class.java)
我在 Url 类中创建了 Url,比如 Url.kt
class Url
companion object
const val BASE_URL = "your base url"
const val URL = "your url"
为 API 调用创建接口
interface CallApi
@GET(Url.URL)
//query needed if there is any query
fun getApi(@Query("limit") limit: Int):
//model class is needed
Observable<Model.Result>
根据你的响应创建一个模型类,示例响应是
"data":
"children": [
"data":
"author": "",
"thumbnail":"",
"title":""
]
为了创建它的模型类,创建一个对象,比如模型
object Model
data class Result(val data: Data)
data class Data(val children: List<Children>)
data class Children(val data: Datas)
data class Datas(val author: String,val thumbnail: String,val title: String)
然后创建一个样板类来从可以从任何活动调用的 api 中执行数据获取
class ApiData
companion object
const val count = 10
val api by lazy Connect.callApi()
var disposable: Disposable? = null
fun apiData(callback:Response)
disposable = api.getApi(count)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe (
result ->
callback.data(result,true)
, error ->
error.printStackTrace()
)
interface Response
fun data(data:Model.Result,status:Boolean)
现在可以从像这样的活动中调用它,
ApiData.apiData( object :ApiData.Response
override fun data(data: Model.Result, status: Boolean)
if(status)
val items:List<Model.Children> = data.data.children
)
【讨论】:
【参考方案3】:您可以使用Retrofit
或AsyncTask
,例如AsyncTask
:
class getData() : AsyncTask<Void, Void, String>()
override fun doInBackground(vararg params: Void?): String?
override fun onPreExecute()
super.onPreExecute()
override fun onPostExecute(result: String?)
super.onPostExecute(result)
对于Retrofit
,请检查这个可怕的tutorial
【讨论】:
快速说明,从 Android R 开始,AsyncTask 已被弃用。developer.android.com/reference/android/os/AsyncTask【参考方案4】:首先在AndroidManifest.xml中添加权限
<uses-permission android:name="android.permission.INTERNET" />
二、安装谷歌依赖,Volley包
obs:volley 是用于进行 JSON 调用的官方 Google 软件包
链接:https://github.com/google/volley
访问项目结构
点击依赖
在所有依赖项中单击 +
点击库依赖
找到凌空并点击搜索
点击确定后点击应用,完成。
创建一个名为 RequestJSON 的新类,在我的例子中我使用的是 Kotlin
import android.app.Activity
import com.android.volley.*;
import com.android.volley.toolbox.JsonObjectRequest
import com.android.volley.toolbox.Volley
import org.json.JSONObject
import java.lang.Exception
class RequestJSON
private val baseURL: String = "[PROTOCOL]://[HOST]:[PORT]/";
private var url: String = "";
private var method: String = "GET";
private var requestData: JSONObject = JSONObject();
private var queryString: String = "";
companion object Factory
fun instance(): RequestJSON = RequestJSON();
fun setURL(url: String): RequestJSON
this.url = url;
return this;
fun setMethod(method: String): RequestJSON
this.method = method.toLowerCase();
return this;
fun setData(data: JSONObject): RequestJSON
this.requestData = data;
return this;
private fun appendQuery(array: Array<String>, element: String): Array<String>
val list: MutableList<String> = array.toMutableList();
list.add(element);
return list.toTypedArray();
fun setQuery(query: JSONObject) : RequestJSON
// limpa o queryString
this.queryString = "";
// obtendo as chaves do json
val keys = query.keys();
// criando array para conter as querys
var querys: Array<String> = arrayOf();
// obtendo os valores atravéz da chave e adicionando no array
for(key in keys)
querys = this.appendQuery(querys, key + "=" + query.get(key));
// verifica se existe valores no array
// para conversão em stringQuery
if (querys.size > 0)
this.queryString += "?";
val size = querys.size;
var count = 0;
while (count < size)
var querystring = "";
if (count == 0)
querystring = querys[count];
else
querystring = "&" + querys[count];
this.queryString += querystring;
count++;
return this;
private fun getMethod(): Int
return when(this.method)
"get" ->
Request.Method.GET;
"post" ->
Request.Method.POST;
"put" ->
Request.Method.PUT;
"delete" ->
Request.Method.DELETE;
else -> Request.Method.GET;
fun send(context: Activity, responseListiner: (response: JSONObject) -> Unit, errorListiner: (error: Exception) -> Unit)
val queue = Volley.newRequestQueue(context);
var url = this.baseURL + this.url + this.queryString;
var data: JSONObject = this.requestData;
// limpando queryString após ser utilizado
this.queryString = "";
// limpando url após ser utilizado
this.url = "";
// limpando requestData após ser utilizado
this.requestData = JSONObject();
val jsonObjectRequest = JsonObjectRequest(this.getMethod(), url, data, fun (response)
responseListiner(response);
, fun (error)
errorListiner(error);
)
// adicionando requesição ao queue
queue.add(jsonObjectRequest);
测试使用
fun responseApiSuccess(response: JSONObject)
Log.i("request-success", response.toString());
fun responseApiError(error: Exception)
Log.e("request-error", error.toString());
fun callAPI()
var queryObject: JSONObject = JSONObject();
queryObject.put("teste", "valor01");
try
RequestJSON.instance().setURL("/").setMethod("GET").setQuery(queryObject).send(this, this::responseApiSuccess, this::responseApiError);
catch (error: Exception)
error.printStackTrace();
【讨论】:
【参考方案5】:Retrofit 是在 Android 上使用 API 的好工具。 Here 是我找到的关于如何在 Kotlin 上使用 Retrofit 的教程
【讨论】:
以上是关于如何在 Kotlin 中发出 API 请求?的主要内容,如果未能解决你的问题,请参考以下文章
如何在一个 Visual Studio 解决方案中的 2 个内部 API 之间发出 API 请求?