關於Observable interval定時任務中止問題

本文不分析操做符的使用方法,主要分析interval輪詢中如何來中止。服務器

最近在項目中使用RxJava,RxAndroid;主要運用於網絡請求,可是項目中有用到定時任務,每隔20s去更新數據,所以想到RxJava中有定時器操做符,再加上已經引入RxJava,鏈式請求就完成了,詳見代碼:網絡

Observable.interval(0, 20, TimeUnit.SECONDS)
	.doOnSubscribe {
		mDisposable = it
	}
	.flatMap {
		return@flatMap DataUtils.API_SERVICE.getQrCode(userId)
	}
	.map {
		val body = it.string()
		val str = body.substring(body.indexOf(",") + 1)
		val decodedString = Base64.decode(str, Base64.DEFAULT)
		return@map BitmapFactory.decodeByteArray(decodedString, 0, decodedString.size)
	}
	.compose(ThreadFromUtils.defaultSchedulers())
	.subscribe({
		dismissProgressDialog()
		qr_code.setImageBitmap(it)
	}, {
		dismissProgressDialog()
		var msg = when (it) {
			is SocketTimeoutException -> "網絡鏈接超時!"
			is ConnectException -> "鏈接不上服務器,請檢查網絡連接!"
			is IOException -> "流鏈接意外結束,請稍候重試!"
			is HttpException -> "網絡出現異常,請稍候重試!"
			is JsonSyntaxException -> "數據解析出現錯誤!"
			else -> it.localizedMessage
		}
		if (msg.isNullOrEmpty()) {
			msg = "出現錯誤,請稍候重試!"
		}
		showErrorToast(msg)
	})

(居然麼有Kotlin選項,將就看看吧。)鏈式請求也在項目中運用不少,這裏用到flatmap和map:flatmap主要返回獲取二維碼請求->而後在map中生成bitmap->最後展現。這種方法看着舒服,可是也有問題:當接收到error的時候,定時器就會退出。所以不得不改變寫法,詳見代碼:測試

Observable.interval(0, 20, TimeUnit.SECONDS)
	.doOnSubscribe {
		mDisposable = it
	}
	.subscribeOn(Schedulers.computation())
	.observeOn(AndroidSchedulers.mainThread())
	.subscribe {
		refreshQrCode()
	}

就是把獲取二維碼代碼的請求在定時器每發送一次onNext中去執行,這樣就解決了當接收到error的時候,定時器就會退出的問題。可是測試提出Bug說,離開這個頁面還在刷新二維碼數據。所以不得不在onPause裏面把mDisposable.cancel()取消掉,若是能夠也就萬事大吉了;不想這樣不只沒有用,還引出一個Bug,內心那個憋屈吖,只能打碎牙齒往肚子裏咽。Bug截圖如圖示: Bug圖片日誌

經細看是由於刷新二維碼都會有一個彈框等待,因爲Activity已經銷燬,因此Dialog add window 失敗。 想着先騙過測試吧,因而在獲取二維碼數據時,增長了一個判斷,if(activity != null && !activity!!.isFinishing)時去獲取,不然不獲取二維碼數據。code

這樣只是應付測試,本身還要找結局方案,因而搜索Observable interval stop,在StackOverflow是找到解決方案,最後修改成,詳見代碼:blog

Observable.interval(0, 20, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
	.takeWhile {
		!mStop
	}
	.subscribe {
		refreshQrCode()
	}

mStop是是否中止標誌,在onResume()中賦值爲false,在onPause()中賦值爲true,而後測試沒有再打印日誌,應該是中止了,再次進入時又從新打印日誌。至此中止定時任務以及延申的問題都解決了,在此記錄一下,但願對採坑的朋友有幫助。圖片

相關文章
相關標籤/搜索