0

I'm new in Kotlin, i want to create an android mobile app.I use Android studio 3.3,the Android API level 28. I have used a swagger to get all my RESTful web service, thus, i have the android-client-generated the file that contains all the web service. As a start, I created an android interface for authentication with Email and Password". Among the web service available, "apiMobileUsersGetByFireBaseIDGet". This Ws, use the firebase Id to authenticate.
I create a kotlin class AUthentication as the following :

class Authentication : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_authentication)
        var email = editTextEmail.text
        var password = editTextPassword.text

        FirebaseApp.initializeApp(this@Authentication)
        val auth = FirebaseAuth.getInstance()

        buttonlogin.setOnClickListener {
            auth.signInWithEmailAndPassword(email.toString(), password.toString())
                .addOnCompleteListener(this) { task ->
                    if (task.isSuccessful) {
                        println("success")
                        if (verifyAvailableNetwork(this@Authentication)) {
                            try {
                                CoroutineScope(Dispatchers.Main).launch {
                                    val user = MobileApi().apiMobileUsersGetByFireBaseIDGet(auth.currentUser!!.uid)
                                    if (user == UsersData()) {
                                        var intent = Intent(this@Authentication, MainActivity::class.java)
                                        intent.putExtra("id", auth.currentUser?.email)
                                        startActivity(intent)
                                    }
                                }

                            } catch (e: ClientException) {
                                println("4xx response calling apiMobileUsersGetByFireBaseIDGet")
                                e.printStackTrace()
                            } catch (e: ServerException) {
                                println("5xx response calling apiMobileUsersGetByFireBaseIDGet ")
                                e.printStackTrace()
                            }
                        }
                    } else {
                        println("Error: ${task.exception?.message}")
                    }
                }


        }

    }

}

i added alse the internet permission in the AndroidManifest.xml. My problem is when i run my app in my mobile phone, a "NetworkOnMainThreadException" sets off.I tried for several times to correct this error.I'm really stuck. The error description as the following :

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.app.homecraft, PID: 32245
    android.os.NetworkOnMainThreadException
        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1285)
        at java.net.InetAddress.lookupHostByName(InetAddress.java:434)
        at java.net.InetAddress.getAllByNameImpl(InetAddress.java:255)
        at java.net.InetAddress.getAllByName(InetAddress.java:218)
        at okhttp3.Dns$Companion$SYSTEM$1.lookup(Dns.kt:48)
        at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.kt:157)
        at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.kt:122)
        at okhttp3.internal.connection.RouteSelector.next(RouteSelector.kt:70)
        at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:203)
        at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:108)
        at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:76)
        at okhttp3.internal.connection.Transmitter.newExchange$okhttp(Transmitter.kt:162)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:36)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:117)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:90)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:84)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:117)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:90)
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:84)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:117)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:71)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:117)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:90)
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.kt:184)
        at okhttp3.RealCall.execute(RealCall.kt:67)
        at io.swagger.client.apis.MobileApi.apiMobileUsersGetByFireBaseIDGet(MobileApi.kt:4096)
        at com.app.homecraft.Authentication$onCreate$1$1$1.invokeSuspend(Authentication.kt:38)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:233)
        at android.os.Handler.handleCallback(Handler.java:743)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:150)
        at android.app.ActivityThread.main(ActivityThread.java:5639)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:799)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:689)
MimiSoft
  • 41
  • 4
  • 10
  • In recent Android versions you cannot make http calls directly in the main thread, that's the cause of the error. Maybe you can use coroutines to execute the call in another thread (IO thread for example) – Romain Goutte-Fangeas Jun 21 '19 at 10:02
  • How can i do this, in my code i used the coroutine – MimiSoft Jun 21 '19 at 10:06
  • Change "Dispatchers.Main" to "Dispatchers.IO" to specify that you want your coroutine to run on an IO thread. Maybe you will need to run the "signInWithEmailAndPassword" method in a coroutine too. – Romain Goutte-Fangeas Jun 21 '19 at 10:10
  • i change to "Dispatchers.IO" as you told me, a new error appear as the following : E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1 Process: com.app.homecraft, PID: 11512 java.lang.ClassNotFoundException: Didn't find class "java.time.LocalDateTime" on path: DexPathList[[zip file "/data/app/com.app.homecraft-2/base.apk", zip file "/data/app/com.app.homecraft-2/split_lib_dependencies_apk.apk", zip file "/data/app/com.app.homecraft-2/split_lib_slice_0_apk.apk", zip file ....... – MimiSoft Jun 21 '19 at 10:17

3 Answers3

0

you must make requests to the network only in background stream, otherwise you will receive an error when you try to make a request

headofmobile
  • 188
  • 4
0

You error says that you are performing some heavy work on the UI which would bring some freezing of it, or worst. Crashing. In that case you should move your call on the background thread, which means that the UI will continue to run normally while the network request will perform indipendently of the UI. Since you are using Kotlin coroutines you might wanna change the Dispatchers.Main with Dispatchers.IO. This is a simple example.

coroutineDispatcher
  • 7,718
  • 6
  • 30
  • 58
  • i change to "Dispatchers.IO" as you told me, a new error appear as the following : E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1 Process: com.app.homecraft, PID: 11512 java.lang.ClassNotFoundException: Didn't find class "java.time.LocalDateTime" on path: DexPathList[[zip file "/data/app/com.app.homecraft-2/base.apk", zip file "/data/app/com.app.homecraft-2/split_lib_dependencies_apk.apk", zip file "/data/app/com.app.homecraft-2/split_lib_slice_0_apk.apk", zip file ....... – MimiSoft Jun 21 '19 at 10:44
  • I couldn't find what's the class not found – MimiSoft Jun 24 '19 at 08:15
0

there is a line which is

//TODO("Fill in more types!")

in your ApiClient.kt file (generated by swagger). you need to change that line to get rid of this exception. I dont know what to replace with, but that line is the source of the problem.

ycannot
  • 1,807
  • 1
  • 9
  • 20