【问题标题】:How to make an API request in Kotlin?如何在 Kotlin 中发出 API 请求?
【发布时间】:2017-12-26 10:14:01
【问题描述】:

总的来说,我对 Kotlin 和 API 非常陌生,找不到使用这种语言创建 API 请求的语法。我正在创建网站的移动版本,因此我正在使用 Android Studio 为已经建立的后端创建新的 UI。创建请求的步骤和语法是什么?任何帮助都深表感谢。

【问题讨论】:

标签: android rest kotlin


【解决方案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())
        })
    }
}

以下是其他库的一些更复杂的示例:

【讨论】:

  • 非常感谢您的详细回复。这肯定会帮助我取得一些进步。
  • 任何从 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】:

    您可以使用RetrofitAsyncTask,例如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

    【讨论】:

    【解决方案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 的教程

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-01-14
        • 1970-01-01
        • 2021-03-08
        • 2012-11-19
        • 2021-04-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多