【问题标题】:Why Android is blocking my OkHttp Request为什么 Android 会阻止我的 OkHttp 请求
【发布时间】:2020-02-11 19:18:11
【问题描述】:

我尝试使用 OkHttp 调用我的 API 但 android 不希望我这样做! 我读到我需要让我的类扩展 AsyncTask 但它不起作用 也许我只是不知道如何使其异步,但这是我尝试使其异步之前的代码 你能帮帮我吗?

这是我的 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)

【问题讨论】:

  • 发布您的错误日志
  • @SaurabhBhandari 对不起
  • 它在日志中明确提到你在主线程中使用网络调用所以你可以使用AsyncTask或Retrofit(它使用Okhttp)。不要忘记在您的清单文件中添加互联网权限
  • @SaurabhBhandari 我不知道该怎么做! (这是我在kotlin中的第一个应用)并添加了权限
  • 如果您已经在 java 中完成了此操作,只需将其复制并粘贴到 kotlin 文件中,Android Studio 将为您完成其余工作。改造请点击此链接antonioleiva.com/retrofit-android-kotlin

标签: android kotlin okhttp


【解决方案1】:

如上所述,您不能在MainThread 上进行网络请求。因此,一种方法是AsyncTask as:

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

    }

}

【讨论】:

    【解决方案2】:

    正如错误所说,您正在主线程上进行网络调用,这是被禁止的,因为网络调用是一个很长的操作。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-17
      • 2020-09-05
      • 2012-05-17
      • 2011-03-27
      • 1970-01-01
      • 2015-08-20
      相关资源
      最近更新 更多