AsyncTask没有泄漏
这个AsyncTask类应该是静态的,否则可能发生泄漏
为什么我的AsyncTask不起作用?
调用: PlacesTask(this).execute(...)
码:
private class PlacesTask internal constructor(activity: MainActivity) : AsyncTask<String, Int, String>() { var data: String? = null private val mRef: WeakReference<MainActivity> = WeakReference(activity) override fun doInBackground(vararg url: String): String? { try { data = MainActivity().downloadUrl(url[0]) } catch (e: Exception) { Log.d("Background Task", e.toString()) } return data } override fun onPostExecute(result: String) { val asyncTaskLeak = mRef.get() if (asyncTaskLeak != null) SetPlaceTask().execute(result) } } private class SetPlaceTask : AsyncTask<String, Int, List<HashMap<String, String>>>() { var places: List<HashMap<String, String>>? = null override fun doInBackground(vararg jsonData: String): List<HashMap<String, String>>? { try { places = PlaceJSONParser().parse(JSONObject(jsonData[0])) } catch (e: Exception) { Log.d("Exception", e.toString()) } return places } override fun onPostExecute(list: List<HashMap<String, String>>) { ... } } @Throws(IOException::class) private fun downloadUrl(strUrl: String): String { var data = "" var iStream: InputStream? = null var urlConnection: HttpURLConnection? = null try { urlConnection = URL(strUrl).openConnection() as HttpURLConnection urlConnection.connect() iStream = urlConnection.inputStream val br = BufferedReader(InputStreamReader(iStream!!)) val sb = StringBuilder() var line: String? = null while ({line = br.readLine(); line }() != null) sb.append(line) data = sb.toString() br.close() } catch (e: Exception) { Log.d("downloading url", e.toString()) } finally { if (iStream != null) iStream.close() if (urlConnection != null) urlConnection.disconnect() } return data }
错误:java.lang.IllegalArgumentException:指定为非null的参数为null:方法kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull,参数result
请帮忙。 我错过了什么?
如例外所述,参数result
为null
而您将其定义为不可空。
由于该参数是由doInBackground
返回的值,因为downloadUrl
抛出一个异常, data
变量为null
。
要修复它,请执行以下任一选项:
- 当发生异常时定义一个非null的默认返回值,确保
doInBackground
永远不会返回null。 - 将
onPostExecute
的参数类型更改为String?
并处理发生异常时可能为空的情况。
我明白了
-
AsyncTask
应该是static
-
AsyncTask
移动到 – >companion object {}
。 - WeakReference –
AsyncTask
没有泄漏(好的exp。)
示例:没有泄漏的AsyncTask
override fun onPause() { super.onPause() ... when { placesTask != null -> { placesTask!!.cancel(true) placesTask = null } setPlacesTask != null -> { setPlacesTask!!.cancel(true) setPlacesTask = null } } } ... @Throws(IOException::class) private fun downloadUrl(strUrl: String): String { var data = "" var iStream: InputStream? = null var urlConnection: HttpURLConnection? = null try { urlConnection = URL(strUrl).openConnection() as HttpURLConnection urlConnection.connect() iStream = urlConnection.inputStream val br = BufferedReader(InputStreamReader(iStream!!)) val sb = StringBuilder() var line: String? = null while ({line = br.readLine(); line }() != null) sb.append(line) data = sb.toString() br.close() } catch (e: Exception) { Log.d("downloading url", e.toString()) } finally { if (iStream != null) iStream.close() if (urlConnection != null) urlConnection.disconnect() } return data } companion object { ... var placesTask: PlacesTask? = null var setPlacesTask: SetPlaceTask? = null class PlacesTask(mainActivity: MainActivity) : AsyncTask<String, Int, String>() { private val mRef: WeakReference<MainActivity> = WeakReference(mainActivity) override fun doInBackground(vararg url: String): String? { var data: String? = null try { data = mRef.get()?.downloadUrl(url[0]) } catch (e: Exception) { Log.d("Background Task", e.toString()) } return data } override fun onPostExecute(result: String) { setPlacesTask = SetPlaceTask(mRef.get()!!).execute(result) as SetPlaceTask? } } class SetPlaceTask(mainActivity: MainActivity) : AsyncTask<String, Int, List<HashMap<String, String>>>() { private val mRef: WeakReference<MainActivity> = WeakReference(mainActivity) override fun doInBackground(vararg jsonData: String): List<HashMap<String, String>>? { var places: List<HashMap<String, String>>? = null try { places = PlaceJSONParser().parse(JSONObject(jsonData[0])) } catch (e: Exception) { Log.d("Exception", e.toString()) } return places } override fun onPostExecute(list: List<HashMap<String, String>>) { for (i in list.indices) { val hmPlace = list[i] mRef.get()?.parkingLatLng = LatLng(hmPlace["lat"]!!.toDouble(), hmPlace["lng"]!!.toDouble()) mRef.get()?.mMarkerPlaceLink!!.put(mRef.get()?.map!!.addMarker(MarkerOptions().icon(mRef.get()?.vectorToBitmap(R.drawable.ic_local_parking_black_12dp, ContextCompat.getColor(mRef.get()?.applicationContext, R.color.colorPrimaryDark))).position(mRef.get()?.parkingLatLng!!).title(hmPlace["place_name"] + "\n" + hmPlace["vicinity"])).id, hmPlace["reference"].toString()) mRef.get()?.map!!.addCircle(CircleOptions().center(mRef.get()?.parkingLatLng).radius(1.0).strokeColor(Color.BLACK).fillColor(Color.WHITE).strokeWidth(1f).zIndex(1f)) } } } }
调用: placesTask = PlacesTask(this).execute("https://maps.googleapis.com/maps/api/place/nearbysearch/json?location="...) as PlacesTask?
祝你好运!