Почему Android блокирует мой запрос OkHttp - PullRequest
0 голосов
/ 11 февраля 2020

Я пытался вызвать мой API с помощью OkHttp, но android не хочет, чтобы я это делал! Я прочитал, что мне нужно, чтобы мой класс расширял AsyncTask, но он не работает, может быть, я просто не знаю, как сделать это asyn c, но вот код, прежде чем я попытался сделать его асинхронным, можете ли вы помочь мне?

вот мой пакет класса OkHttpHelper com.example.mygostyle

import android.content.Context
import android.os.AsyncTask
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
import okhttp3.Request
import org.json.JSONObject
import java.io.IOException


class OkHttpHelper {

    var client = OkHttpClient()
    var token : String
    init{
        token = ""
    }

    fun login(un: String, pwd: String, context: Context) : Boolean{

        val urlBuilder = HttpUrl.Builder()
            .scheme("https")
            .host("dev.api.gostyle.ovh")
            .addPathSegment("api")
            .addPathSegment("user")
            .addPathSegment("auth")
            .addQueryParameter("username",un)
            .addQueryParameter("password",pwd)
            .build()

        var request = Request.Builder()
            .url(urlBuilder)
            .build()

        client.newCall(request).execute().use { response ->
            if (!response.isSuccessful) throw IOException("Unexpected code $response")
            val responseData = response.body?.string()
            val json = JSONObject(responseData)
            val owner = json.getString("token")
            if(response.code == 200) {
                saveToken(context, owner)
                return true
            }
            return false
        }
    }

    fun saveToken(context: Context, token : String){
        val sharedPreference = SharedPreference(context)
        sharedPreference.save("MyGoStyleToken",token)

    }

}

вот мой пакет активности входа com.example.mygostyle

import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.content.Intent
import android.view.Window
import android.view.WindowManager
import android.widget.EditText


class LoginActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        this.requestWindowFeature(Window.FEATURE_NO_TITLE)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)

        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        this.setContentView(R.layout.activity_login);

        val loginbtn = findViewById<Button>(R.id.loginbtn)

        loginbtn.setOnClickListener(){
            login(this)
        }
    }

    fun login(context: Context){
        var okHttpHelper = OkHttpHelper()
        val uninput = findViewById<EditText>(R.id.username_input).text.toString()
        val pwdinput = findViewById<EditText>(R.id.password_input).text.toString()
        if(okHttpHelper.login(uninput,pwdinput,context)) {
            val gameActivity = Intent(this@LoginActivity, MyPromosActivity::class.java)
            startActivity(gameActivity)
        }

    }


}

журнал ошибок:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.mygostyle, PID: 20075
    android.os.NetworkOnMainThreadException
        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1450)
        at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:102)
        at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:90)
        at java.net.InetAddress.getAllByName(InetAddress.java:787)
        at okhttp3.Dns$Companion$SYSTEM$1.lookup(Dns.kt:48)
        at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.kt:160)
        at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.kt:125)
        at okhttp3.internal.connection.RouteSelector.next(RouteSelector.kt:71)
        at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:199)
        at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:109)
        at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:77)
        at okhttp3.internal.connection.Transmitter.newExchange$okhttp(Transmitter.kt:162)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:35)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:82)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:84)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:71)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.kt:184)
        at okhttp3.RealCall.execute(RealCall.kt:66)
        at com.example.mygostyle.OkHttpHelper.login(OkHttpHelper.kt:36)
        at com.example.mygostyle.LoginActivity.login(LoginActivity.kt:34)
        at com.example.mygostyle.LoginActivity$onCreate$1.onClick(LoginActivity.kt:26)
        at android.view.View.performClick(View.java:6294)
        at android.view.View$PerformClick.run(View.java:24770)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

Ответы [ 2 ]

2 голосов
/ 11 февраля 2020

Как указано, вы не можете выполнять сетевые запросы на MainThread. Таким образом, один из способов сделать это будет AsyncTask как:

class LoginActivity : AppCompatActivity() {

    fun login(context: Context){

        AsyncTask.execute {

            var okHttpHelper = OkHttpHelper()
            val uninput = findViewById<EditText>(R.id.username_input).text.toString()
            val pwdinput = findViewById<EditText>(R.id.password_input).text.toString()
            if(okHttpHelper.login(uninput,pwdinput,context)) {
                val gameActivity = Intent(this@LoginActivity, MyPromosActivity::class.java)
                startActivity(gameActivity)
            }
        }

    }

}
0 голосов
/ 11 февраля 2020

Как говорится в сообщении об ошибке, вы выполняете сетевые вызовы в главном потоке, и это запрещено, поскольку сетевой вызов - это очень длительная операция.

Функция execute выполняет запрос API в синхронизированном режиме. в то время как функция enqueue делает это асинхронным способом, как вы, вероятно, знаете, когда вы хотите сделать асинхронный вызов, вы не можете возвращать вещи из своей функции, потому что код больше не работает в последовательном порядке, поэтому вы должны создайте интерфейс, похожий на обратный вызов.

interface MyCallback {
    fun onResult(result: bool)
}


fun login(un: String, pwd: String, context: Context, myCallback: MyCallback) {

        val urlBuilder = HttpUrl.Builder()
            .scheme("https")
            .host("dev.api.gostyle.ovh")
            .addPathSegment("api")
            .addPathSegment("user")
            .addPathSegment("auth")
            .addQueryParameter("username",un)
            .addQueryParameter("password",pwd)
            .build()

        var request = Request.Builder()
            .url(urlBuilder)
            .build()

        client.newCall(request).enqueue(object: Callback {
          override public fun onFailure(call: Call, e: IOException) {
             throw IOException("Unexpected code $response")
          }
          override public fun onResponse(call: Call, response: Response) {
             if (!response.isSuccessful) throw IOException("Unexpected code $response")
             val responseData = response.body?.string()
             val json = JSONObject(responseData)
             val owner = json.getString("token")
             if(response.code == 200) {
                  saveToken(context, owner)
                  myCallback,onResult(true)
             }
             myCallback,onResult(false)
         }
       })
    }

Таким образом, не будет никакого типа возврата для функции входа в систему, и вы можете вызвать эту функцию таким способом.

class LoginActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        this.requestWindowFeature(Window.FEATURE_NO_TITLE)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)

        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        this.setContentView(R.layout.activity_login);

        val loginbtn = findViewById<Button>(R.id.loginbtn)

        loginbtn.setOnClickListener(){
            login(this, object : MyCallback {
               public override fun onResult(result: Boolean) {
                  // Do something with the result returned
               }
        })
    }

    fun login(context: Context, callback, MyCallback){
        var okHttpHelper = OkHttpHelper()
        val uninput = findViewById<EditText>(R.id.username_input).text.toString()
        val pwdinput = findViewById<EditText>(R.id.password_input).text.toString()
        if(okHttpHelper.login(uninput,pwdinput,context, callback)) {
            val gameActivity = Intent(this@LoginActivity, MyPromosActivity::class.java)
            startActivity(gameActivity)
        }

    }


}
...