Android WebApp恢复后刷新按钮持续旋转问题求助
Android WebApp刷新按钮切后台后持续旋转问题修复
问题描述
开发个人网站的Android WebApp时,给刷新按钮添加了旋转动画用于页面刷新。但切换到其他应用再返回该App后,刷新按钮会开始缓慢持续旋转,日志未发现异常。
相关代码
Kotlin代码(MainActivity)
class MainActivity : AppCompatActivity() { //define the variables here val weburl = "https://techdecipher.com/" lateinit var backhomebuttom: Button lateinit var scrollToTopButton: Button lateinit var scrollToBottomButton: Button lateinit var webView: WebView lateinit var refreshButton: Button private var isRefreshing = false val TAG = "Main Activity" private var rotateAnimator: ObjectAnimator? = null @RequiresApi(Build.VERSION_CODES.Q) @SuppressLint("SetJavaScriptEnabled") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); setContentView(R.layout.activity_main) Log.d(TAG, "onCreate: ") // assign the id to each button webView = findViewById(R.id.webView) backhomebuttom = findViewById(R.id.backhomebuttom) scrollToTopButton = findViewById(R.id.scrollToTopButton) scrollToBottomButton = findViewById(R.id.scrollToBottomButton) refreshButton = findViewById(R.id.refreshButton) // network check // networkcheck() //call loadwebrulfunction loadweburlfunction() // reload button is clicked refreshButton.setOnClickListener { Log.d(TAG, "onCreate: reload") if (!isRefreshing) { // 使用ObjectAnimator实现旋转动画 rotateAnimator = ObjectAnimator.ofFloat(refreshButton, "rotation", 0f, 360f).apply { duration = 500 interpolator = LinearInterpolator() repeatCount = ObjectAnimator.INFINITE start() } isRefreshing = true // Reload the website webView.reload() // 使用lifecycleScope确保任务随Activity生命周期销毁 lifecycleScope.launch { delay(1000) stopRefreshAnimation() } } } } // load web url function on webview @RequiresApi(Build.VERSION_CODES.Q) @SuppressLint("SetJavaScriptEnabled") private fun loadweburlfunction() { webView.settings.javaScriptEnabled = true webView.setBackgroundColor(Color.WHITE) webView.webChromeClient = WebChromeClient() webView.webViewClient = WebViewClient() webView.loadUrl(weburl) } private fun stopRefreshAnimation() { rotateAnimator?.cancel() refreshButton.rotation = 0f // 重置按钮旋转角度 isRefreshing = false } override fun onResume() { super.onResume() stopRefreshAnimation() } override fun onPause() { super.onPause() Log.d(TAG, "onPause: ") stopRefreshAnimation() // 后台时强制停止动画 } override fun onRestart() { super.onRestart() Log.d(TAG, "onRestart: ") stopRefreshAnimation() } override fun onDestroy() { super.onDestroy() Log.d(TAG, "onDestroy: ") stopRefreshAnimation() } }
XML布局代码
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/swipeRefreshLayout" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <!-- WebView to display content --> <WebView android:id="@+id/webView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/buttonContainer" /> <!-- Button Container at the bottom --> <LinearLayout android:layout_width="match_parent" android:layout_height="60dp" android:gravity="center" android:id="@+id/buttonContainer" android:layout_alignParentBottom="true"> <!-- Refresh Button --> <Button android:id="@+id/refreshButton" android:layout_width="40dp" android:background="@drawable/refresh_icon" android:layout_height="40dp" android:contentDescription="@string/rotate_to_refres" /> <!-- Home Button --> <Button android:id="@+id/backhomebuttom" android:layout_width="130dp" android:layout_height="40dp" android:layout_gravity="center" android:layout_marginStart="15dp" android:text="@string/homepage" android:textStyle="bold" android:background="@drawable/rounded_button_selector" android:gravity="center" android:padding="0dp" /> <!-- Top Button --> <Button android:layout_width="40dp" android:layout_gravity="center" android:layout_marginStart="15dp" android:id="@+id/scrollToTopButton" android:background="@drawable/scrollup" android:layout_height="40dp"/> <!-- Bottom Button --> <Button android:layout_width="40dp" android:layout_gravity="center" android:layout_marginStart="15dp" android:id="@+id/scrollToBottomButton" android:background="@drawable/scrolldown" android:layout_height="40dp" /> <!-- Share Button --> <Button android:layout_width="40dp" android:layout_marginStart="15dp" android:background="@drawable/share" android:layout_height="40dp" /> </LinearLayout> </RelativeLayout>
问题原因与修复说明
- 旧动画框架缺陷:原代码使用的
RotateAnimation属于旧视图动画框架,与View生命周期绑定松散,Activity后台恢复时系统可能自动重启未正确停止的动画。改用ObjectAnimator属性动画,直接操作View的rotation属性,生命周期一致性更好。 - 后台任务不可靠:原
Handler().postDelayed在Activity进入后台后可能被系统延迟或丢弃,导致isRefreshing状态未及时重置。改用lifecycleScope.launch,任务会随Activity销毁自动取消,避免内存泄漏和状态不一致。 - 生命周期未全面覆盖:原代码仅在
onResume/onRestart判断isRefreshing后停止动画,但后台时动画可能已处于异常状态。修改为在onPause/onResume/onRestart/onDestroy中强制调用stopRefreshAnimation,确保任何场景下动画都能被正确停止并重置状态。
内容的提问来源于stack exchange,提问作者Pranav Chaudhari
相关产品推荐
相关产品推荐

