如何在Kotlin中发出API请求?

时间:2017-07-20 15:40:29

标签: android rest kotlin

我对Kotlin和API一般都是新手,并且找不到使用这种语言创建API请求的语法。我正在创建一个网站的移动版本,所以我使用Android Studio为已经建立的后端创建一个新的UI。创建请求的步骤和语法是什么?非常感谢任何帮助。

5 个答案:

答案 0 :(得分:29)

一旦你有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())
        })
    }
}

下面是一些其他库的更复杂的例子:

答案 1 :(得分:5)

您可以使用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检查这个awsome tutorial

答案 2 :(得分:2)

Retrofit是在Android上使用API​​的好工具。 Here是我在如何在Kotlin上使用Retrofit

的教程

答案 3 :(得分:2)

首先在AndroidManifest.xml中添加权限

  <uses-permission android:name="android.permission.INTERNET" />

二、安装Google依赖,Volley包

obs: volley 是用于进行 JSON 调用的官方 Google 软件包

链接:https://github.com/google/volley

访问项目结构enter image description here

点击依赖项

enter image description here

在所有依赖项中单击 + enter image description here

点击图书馆依赖

enter image description here

找到并点击搜索

enter image description here

点击确定后点击应用,完成。

创建一个名为 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();
    }
}

答案 4 :(得分:1)

我已经使用改造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":""
                     }
                 }]
          }
 }

要创建其模型类,请创建一个名为Model的对象

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
        }
    }

})