0

In these below two functions I am getting referrerUrl and addId. I want both of them to be fetched in onCreate but don't know how because it is in try & catch block also the getGaid() function is not running without AsyncTask.

    fun getreferrUrl() {

     //to install referrer client
   val referrerClient = InstallReferrerClient.newBuilder(this).build()
    referrerClient.startConnection(object : InstallReferrerStateListener {

        override fun onInstallReferrerSetupFinished(responseCode: Int) {
            when (responseCode) {
                InstallReferrerResponse.OK -> {
                    // Connection established.
                    try {
                        val response: ReferrerDetails = referrerClient.installReferrer
                        val referrerUrl = response.installReferrer

                                // here we need referrerUrl out from this fuction

                    } catch (e: RemoteException) {
                        e.printStackTrace()
                    }
                }

//

fun getGaid() {
    AsyncTask.execute {

        try {
            val adInfo = AdvertisingIdClient.getAdvertisingIdInfo(this)
            val myId: String = if (adInfo != null) adInfo.id else null.toString()

                       //here we need myId out from this fuction

        } catch (e: java.lang.Exception) {...}
     }  
  }

In onCreate we need both of those strings.

      // In onCreate

                 val url = "http://instbng.com?device_id=$device_id&                             
                            &kd_id=$kd_id&ref=$referrerUrl&gaid=$myId"

                   loadUrl(url)
  • You can’t asynchronously get data and start using it inside onCreate because that would block the main thread. Merging the results of two different async APIs without blocking is tricky, and is greatly simplified if you convert them to suspend functions and use coroutines. – Tenfour04 Nov 26 '21 at 13:59
  • I realized in this case coroutines are not a trivial solution, because InstallReferrerStateListener is not a one-shot callback. It is two separate callbacks built into one so it cannot be turned into a simple suspend function. It could be a Flow that emits two different sealed class types, but that's kind of awkward. – Tenfour04 Nov 27 '21 at 15:03
  • Yeah, with coroutines it would be less possible. – Kushal Sharma Nov 28 '21 at 00:43

1 Answers1

1

Without coroutines, you can put the results in properties, and create a function that uses both properties and call it from both callbacks. I renamed your get... functions to fetch... since they are asynchronous. The word get in a function name implies they are synchronous.

private var referrerUrl: String? = null
private var myId: String? = null

override fun onCreate(bundle: SavedInstanceState?) {
    super.onCreate(bundle)

    //...

    fetchReferrerUrl()
    fetchGaId()
}

// proceeds with workflow if referrerUrl and myId are both available
private fun proceedIfReady() {
    val referrer = referrerUrl ?: return
    val id = myId ?: return
    val url = "http://instbng.com?device_id=$device_id&kd_id=$kd_id&ref=$referrer&gaid=$idd"
    loadUrl(url)
}

fun fetchReferrerUrl() {
    val referrerClient = InstallReferrerClient.newBuilder(this).build()
    referrerClient.startConnection(object : InstallReferrerStateListener {

        override fun onInstallReferrerSetupFinished(responseCode: Int) {
            when (responseCode) {
                InstallReferrerResponse.OK -> {
                    // Connection established.
                    try {
                        val response: ReferrerDetails = referrerClient.installReferrer
                        referrerUrl = response.installReferrer

                        proceedIfReady()

                    } catch (e: RemoteException) {
                        e.printStackTrace()
                    }
                }
            }
        }

        //... handle closed connection callback

    }
}

private fun fetchGaId() {
    AsyncTask.execute {
        try {
            val adInfo = AdvertisingIdClient.getAdvertisingIdInfo(this)
            runOnUiThread { // in a Fragment use view?.post
                myId = if (adInfo != null) adInfo.id else null.toString()
                proceedIfReady()
            }
        } catch (e: java.lang.Exception) {...}
    }
}
Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • Thankyou very much man it really helped me and I learnt this new way without using coroutines. Also, i am really bad at naming functions, thx for the get fetch thing. Though, in fetchGaId method - in runOnUiThread - myId : String = ... can be written as myId = ... . coz it shows error with that. – Kushal Sharma Nov 27 '21 at 11:37
  • Oops, I fixed it. That was a copy-paste error. You can’t redeclare the type of an already declared property or variable. – Tenfour04 Nov 27 '21 at 13:14
  • yeah! that's it. Thanks again @tenfour04 – Kushal Sharma Nov 28 '21 at 00:44