提问者:小点点

如何防止onCreate在doAsync完成之前返回结果


我在这里需要一些帮助(我是一个新的程序员)。 我正在Kotlin写一个应用程序,它要求我根据GPS定位找到当地的餐馆。 一旦我找到它们,我就得把它们还给用户。 我正在工作的具体部分(我已经完成了mapview)是一个餐厅具体细节的列表视图。

我遇到的问题是,在onCreateView(是的,它在一个片段中)返回视图之前,我的doAsync任务没有完成。 因此,视图为空白。 我曾尝试使线程Hibernate,但它会暂停所有内容,包括异步任务。 无论我做什么,当视图返回时,RestaurantList.Size始终为0,视图始终为空。 我可以在日志中看到,该视图在列表被填充之前返回。 我已经在这方面工作了2个星期了。 谁能帮我点忙吗?

以下是我的OnCreateView代码:

 override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val root = inflater.inflate(R.layout.fragment_list, container, false)

        fusedLocationClient = LocationServices.getFusedLocationProviderClient(requireActivity())
        if (checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION)) {
            fusedLocationClient?.lastLocation?.addOnSuccessListener(requireActivity()) { location: Location? ->
                if (location == null) {
                    // TODO, handle it
                } else location.apply {
                    var long = location.longitude
                        var lat = location.latitude
                        // Handle location object
                        var type = "restaurant"
                        var url = getUrl(lat, long, type)

                        doAsync {
                            var googlePlacesData = (URL(url).readText())
                            onComplete {
                                val parser = DataParser()
                                nearbyPlaceList = parser.parse(googlePlacesData)
                    for (i in nearbyPlaceList.indices) {
                         val googlePlace = nearbyPlaceList[i]
                         placeName = googlePlace["place_name"]!!
                         vicinity = googlePlace["vicinity"]
                         id = googlePlace["place_id"]

                         val detailURL = StringBuilder("https://maps.googleapis.com/maps/api/place/details/json?")
                                    detailURL.append("place_id=" + id)
                                    detailURL.append("&key=" + "KEY_GOES_HERE")

                         doAsync {
                            var detailData = (URL(detailURL.toString()).readText())
                            onComplete {
                                val jsonObject: JSONObject
                                val jsonObject2: JSONObject
                                jsonObject = JSONObject(detailData)
                                jsonObject2 = jsonObject.getJSONObject("result")
                                if (!jsonObject2.isNull("name")) {
                                    placeName = jsonObject2.getString("name")
                                }
                                if (!jsonObject2.isNull("place_id")) {
                                    placeId = jsonObject2.getString("place_id")
                                }
                                if (!jsonObject2.isNull("formatted_address")) {
                                    address = jsonObject2.getString("formatted_address")
                                }
                                if (!jsonObject2.isNull("formatted_phone_number")) {
                                    phone = jsonObject2.getString("formatted_phone_number")
                                }
                                if (!jsonObject2.isNull("website")) {
                                    website = jsonObject2.getString("website")
                                }
                                if (!jsonObject2.isNull("rating")) {
                                    rating = jsonObject2.getDouble("rating")
                                }
                                if (bmImg == null) {
                                    var jsonPhotosArray: JSONArray? = null
                                    if (jsonObject2.has("photos")) {
                                        jsonPhotosArray = jsonObject2.getJSONArray("photos")
                                        val obj = jsonPhotosArray.getJSONObject(0)
                                        photoReference = obj.getString("photo_reference")
                                        val photoURL =
                                            StringBuilder("https://maps.googleapis.com/maps/api/place/photo?")
                                        photoURL.append("maxwidth=500")
                                        photoURL.append("&maxheight=500")
                                        photoURL.append("&key=" + "KEY_GOES_HERE")
                                        photoURL.append("&photoreference=" + photoReference)

                                        doAsync {
                                            ImageUrl = URL(photoURL.toString())
                                            val conn =
                                                ImageUrl.openConnection() as HttpURLConnection
                                            conn.setDoInput(true)
                                            conn.connect()
                                            var `is` = conn.getInputStream()
                                            val options = BitmapFactory.Options()
                                            options.inPreferredConfig = Bitmap.Config.RGB_565
                                            bmImg =
                                                BitmapFactory.decodeStream(`is`, null, options)!!
                                            onComplete {
                                                var style = "Restaurant"
                                                var openTil = "7 p.m."
                                                var distance = "0.0"
                                                var empsGoing = "2"
                                                restaurantList.add(ListViewModel(placeName,style,address, openTil, distance, empsGoing, rating, phone))
                                                Log.d("Log", "List Total = " + restaurantList.size)
                                                

                                            }
                                        }
                                    }
                                }
                            }
                                }
                            }
                         }
                    }
                    }
                }
                Toast.makeText(requireContext(), "Listing Nearby Restaurants", Toast.LENGTH_SHORT).show()
            }

        Log.d("Log", "List Total End= " + restaurantList.size)
        val recyclerview = root.findViewById(R.id.rvList) as RecyclerView
        recyclerview.layoutManager = LinearLayoutManager(requireActivity())
        recyclerview.adapter = RecyclerAdapter(restaurantList, requireContext())
        return root
    }

下面是我得到的日志输出:

2020-07-25 07:39:47.354 17576-17576/com.mark.lunchappredesign D/Log: Inside onCreate
2020-07-25 07:39:53.415 17576-17576/com.mark.lunchappredesign D/Log: List Total End= 0
2020-07-25 07:39:53.494 17576-17576/com.mark.lunchappredesign D/Log: ListFragment - url = https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=39.812755,-85.7664&radius=5000&type=restaurant&sensor=true&key=KEY_GOES_HERE
2020-07-25 07:39:53.992 17576-17576/com.mark.lunchappredesign D/Log: DataParser - jsonobject ={"business_status":"OPERATIONAL","geometry":{"location":{"lat":39.80146370000001,"lng":-85.7692799},"viewport":{"northeast":{"lat":39.80274508029151,"lng":-85.7679299197085},"southwest":{"lat":39.80004711970851,"lng":-85.7706278802915}}},"icon":"https:\/\/maps.gstatic.com\/mapfiles\/place_api\/icons\/restaurant-71.png","id":"297878a9f9b57ecb7d7c00c3a695b30ec908c5d4","name":"Subway","opening_hours":{"open_now":false},"photos":[{"height":2988,"html_attributions":["<a href=\"https:\/\/maps.google.com\/maps\/contrib\/116980312202159126535\">Janet Williams<\/a>"],"photo_reference":"CmRaAAAAVQBC5037LqGuRj5bmi0IJg3mYRaZZGWTO--YmFq6iMTRDxWQTEyMILNhI1pjY-T1Ma8Cb_HxvFQc31_Nt-oQv-rOy61APaP5Wytcog
...

...
2020-07-25 07:39:54.918 17576-17576/com.mark.lunchappredesign D/Log: List Total = 1
2020-07-25 07:39:54.931 17576-17576/com.mark.lunchappredesign D/Log: List Total = 2
2020-07-25 07:39:54.942 17576-17576/com.mark.lunchappredesign D/Log: List Total = 3
2020-07-25 07:39:55.022 17576-17576/com.mark.lunchappredesign D/Log: List Total = 4
2020-07-25 07:39:55.034 17576-17576/com.mark.lunchappredesign D/Log: List Total = 5
2020-07-25 07:39:55.034 17576-17576/com.mark.lunchappredesign D/Log: List Total = 6
2020-07-25 07:39:55.083 17576-17576/com.mark.lunchappredesign D/Log: List Total = 7
2020-07-25 07:39:55.091 17576-17576/com.mark.lunchappredesign D/Log: List Total = 8
2020-07-25 07:39:55.126 17576-17576/com.mark.lunchappredesign D/Log: List Total = 9
2020-07-25 07:39:55.131 17576-17576/com.mark.lunchappredesign D/Log: List Total = 10
2020-07-25 07:39:55.172 17576-17576/com.mark.lunchappredesign D/Log: List Total = 11
2020-07-25 07:39:55.183 17576-17576/com.mark.lunchappredesign D/Log: List Total = 12
2020-07-25 07:39:55.194 17576-17576/com.mark.lunchappredesign D/Log: List Total = 13
2020-07-25 07:39:55.203 17576-17576/com.mark.lunchappredesign D/Log: List Total = 14
2020-07-25 07:39:55.273 17576-17576/com.mark.lunchappredesign D/Log: List Total = 15
2020-07-25 07:39:55.278 17576-17576/com.mark.lunchappredesign D/Log: List Total = 16
2020-07-25 07:39:55.310 17576-17576/com.mark.lunchappredesign D/Log: List Total = 17
2020-07-25 07:39:55.410 17576-17576/com.mark.lunchappredesign D/Log: List Total = 18
2020-07-25 07:39:55.611 17576-17576/com.mark.lunchappredesign D/Log: List Total = 19

共1个答案

匿名用户

将这部分代码移入OnComplete块:

    Log.d("Log", "List Total End= " + restaurantList.size)
    val recyclerview = root.findViewById(R.id.rvList) as RecyclerView
    recyclerview.layoutManager = LinearLayoutManager(requireActivity())
    recyclerview.adapter = RecyclerAdapter(restaurantList, requireContext())

无论如何,代码显然不是一个完美的,还有很多需要改进的地方。 并且注意,无论如何,当您添加片段时,它不一定具有远程数据。 通常在创建fragment时进行API调用,然后在oncomplete中,您可以使用数据填充视图。