关于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,而后测试没有再打印日志,应该是中止了,再次进入时又从新打印日志。至此中止定时任务以及延申的问题都解决了,在此记录一下,但愿对采坑的朋友有帮助。图片

相关文章
相关标签/搜索