我有一个活动,在其onCreate()方法上定义了一个带有retainableInstance = true的片段,该片段将进行一些联网,然后将数据发送回该活动。
这是我的回调函数
override fun updateUi(result: ArrayList<Person>?) {
progressBar.visibility = View.GONE
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
if (result != null) {
setAdapter(result)
}
else {
finishNetworking()
val snackBar = Snackbar.make(findViewById(R.id.root_layout),
"Network failure", Snackbar.LENGTH_INDEFINITE)
snackBar.setAction("Try again") {
startDownload()
}
snackBar.show()
}
}
这是我的活动onCreate()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewManager = LinearLayoutManager(this)
progressBar = findViewById(R.id.progress_bar)
recyclerView = findViewById<RecyclerView>(R.id.recycler_view).apply {
setHasFixedSize(true)
layoutManager = viewManager
}
if (savedInstanceState == null) {
hasArgs = false
networkFragment = NetworkFragment.getInstance(supportFragmentManager, SWAPI_URL_PEOPLE, null)
}
else {
hasArgs = true
networking = savedInstanceState.getBoolean("networking", false)
if (networking) {
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
progressBar.visibility = View.VISIBLE
}
if (savedInstanceState.getParcelableArrayList<Person>("persons") != null) {
setAdapter(savedInstanceState.getParcelableArrayList<Person>("persons") as ArrayList<Person>)
}
}
}
这是我的AsyncTask
private class NetworkTask(
callback: NetworkCallback<ArrayList<Person>>,
person: Person?
)
: AsyncTask<String, Int, NetworkTask.Result>() {
private val mCallback: NetworkCallback<ArrayList<Person>>? = callback
private val mPerson: Person? = person
internal class Result {
var mResultValue: ArrayList<Person>? = null
var mException: Exception? = null
constructor(resultValue: ArrayList<Person>?) {
mResultValue = resultValue
}
constructor(exception: Exception) {
mException = exception
}
}
override fun onPreExecute() {
if (mCallback != null) {
if (Build.VERSION.SDK_INT < 23) {
val networkInfo = mCallback.getConnectivityManager().activeNetworkInfo
if (networkInfo?.isConnected == false
|| networkInfo?.type != ConnectivityManager.TYPE_WIFI
&& networkInfo?.type != ConnectivityManager.TYPE_MOBILE) {
mCallback.updateUi(null)
cancel(true)
}
}
else {
val network = mCallback.getConnectivityManager().activeNetwork
val networkCapabilities = mCallback.getConnectivityManager().getNetworkCapabilities(network)
if (networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == false &&
!networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
mCallback.updateUi(null)
cancel(true)
}
}
}
}
override fun doInBackground(vararg urls: String): Result? {
var result: Result? = null
if (!isCancelled && urls.isNotEmpty()) {
val urlString = urls[0]
result = try {
val resultString = downloadUrl(urlString)
if (resultString != null) {
val persons = ArrayList<Person>()
if (mPerson == null) {
Result(getAllPersons(urlString, persons))
}
else {
persons.add(getPersonHomeworldAndVehicles(urlString, mPerson))
Result(persons)
}
} else {
throw IOException("No response received.")
}
} catch (e: Exception) {
Result(e)
}
}
return result
}
override fun onPostExecute(result: Result?) {
mCallback?.apply {
result?.mException?.also { exception ->
updateUi(null)
return
}
result?.mResultValue?.also { resultValue ->
updateUi(resultValue)
return
}
finishNetworking()
}
}
问题是我旋转设备后,当我从asynctask收到回调时,我的视图没有更新,因为当我设置progressBar.visibility = View.GONE时,进度条仍然可见
答案 0 :(得分:0)
好的,现在我看到您从asyncTask函数调用callback.updateUi()
了。
这引起了问题,因为在异步任务中执行操作时,您处于非UI线程中。
为避免此问题,您需要在功能override fun updateUi(result: ArrayList<Person>?)()
内调用runOnUiThread(),并用runOnUiThread块包围所有与UI相关的代码。
示例:
override fun updateUi(result: ArrayList<Person>?) {
runOnUiThread {
progressBar.visibility = View.GONE
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
if (result != null) {
setAdapter(result)
} else {
finishNetworking()
val snackBar = Snackbar.make(findViewById(R.id.root_layout),
"Network failure", Snackbar.LENGTH_INDEFINITE)
snackBar.setAction("Try again") {
startDownload()
}
snackBar.show()
}
}
}