Android开发,用Kotlin语言。在SixthActivity中,要实现点击logout按钮后退出登录的功能。SixthActivity 代码如下: package com.example.activitytest
import android.content.Intent import android.os.Bundle import android.os.Handler import android.os.Looper import android.widget.Button import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import android.widget.TextView import androidx.activity.result.ActivityResultLauncher import java.text.SimpleDateFormat import java.util.*
class SixthActivity : AppCompatActivity() { private lateinit var startForResult: ActivityResultLauncher<Intent> private lateinit var timeTextView: TextView private val handler = Handler(Looper.getMainLooper()) private val updateTimeRunnable = object : Runnable { override fun run() { updateTime() handler.postDelayed(this, 5000) // 每5秒更新一次 } }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.sixth_layout)
timeTextView = findViewById(R.id.timeTextView)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.timeTextView)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
// 开始定时更新时间
handler.post(updateTimeRunnable)
//点击logoutBtn,退出登录
val logoutBtn: Button = findViewById(R.id.logoutBtn)
logoutBtn.setOnClickListener {
val intent = Intent("com.example.activitytest.FORCE_LOGOUT")
sendBroadcast(intent)
}
}
override fun onDestroy() {
super.onDestroy()
// 停止定时更新
handler.removeCallbacks(updateTimeRunnable)
}
private fun updateTime() {
val currentTime = Calendar.getInstance().time
val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
val formattedTime = "当前时间:${dateFormat.format(currentTime)}"
timeTextView.text = formattedTime
}
}
BaseActivityClass 如下: package com.example.activitytest
import android.os.Bundle import android.util.Log import androidx.appcompat.app.AppCompatActivity import android.app.AlertDialog import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter
open class BaseActivityClass : AppCompatActivity() {
private lateinit var receiver: ForceLogoutReceiver
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//打印当前实例类名
Log.d("BaseActivity", javaClass.simpleName)
ActivityCollector.addActivity(this)
}
override fun onResume() {
super.onResume()
val intentFilter = IntentFilter()
intentFilter.addAction("com.example.activitytest.FORCE_LOGOUT")
receiver = ForceLogoutReceiver()
registerReceiver(receiver, intentFilter)
}
override fun onPause() {
super.onPause()
unregisterReceiver(receiver)
}
override fun onDestroy() {
super.onDestroy()
ActivityCollector.removeActivity(this)
}
inner class ForceLogoutReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
AlertDialog.Builder(context).apply {
setTitle("Warning")
setMessage("You are forced to be logout. Please try to login again.")
setCancelable(false) //不可取消
setPositiveButton("确定") { _, _ ->
ActivityCollector.finishAll() // 销毁所有Activity
val i = Intent(context, LoginActivity::class.java)
context.startActivity(i) // 重新启动LoginActivity
}
show()
}
}
}
}
sixth_layout.xml如下:
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/sixLayout" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".SixthActivity">
<TextView
android:id="@+id/timeTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:textSize="18sp"
android:textColor="@android:color/black"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintVertical_bias="0.0"/>
<Button
android:id="@+id/logoutBtn"
android:layout_width="200dp"
android:layout_height="60dp"
android:text="退出登录"
app:layout_constraintTop_toBottomOf="@+id/timeTextView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintVertical_bias="0.1"
android:layout_marginTop="24dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
但是运行后,点击logout按钮后,并没有退出登录,界面没有任何反应。 请分析原因,并解决问题。
从你提供的代码来看,问题可能出在以下几个方面:
SixthActivity 没有继承 BaseActivityClass:你在 BaseActivityClass
中实现了接收广播并处理强制登出的逻辑,但 SixthActivity
并没有继承 BaseActivityClass
,因此它不会接收到广播。
BroadcastReceiver 注册和注销:确保 BroadcastReceiver
在 onResume
中注册,在 onPause
中注销。
ActivityCollector:确保 ActivityCollector
正确实现了 addActivity
和 finishAll
方法。
class SixthActivity : BaseActivityClass() {
// 其余代码保持不变
}
ActivityCollector
正确实现:object ActivityCollector {
private val activities = ArrayList<AppCompatActivity>()
fun addActivity(activity: AppCompatActivity) {
activities.add(activity)
}
fun removeActivity(activity: AppCompatActivity) {
activities.remove(activity)
}
fun finishAll() {
for (activity in activities) {
if (!activity.isFinishing) {
activity.finish()
}
}
activities.clear()
}
}
LoginActivity
存在并正确实现:class LoginActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
// 其他登录逻辑
}
}
package com.example.activitytest
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.widget.Button
import androidx.activity.enableEdgeToEdge
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import android.widget.TextView
import androidx.activity.result.ActivityResultLauncher
import java.text.SimpleDateFormat
import java.util.*
class SixthActivity : BaseActivityClass() { // 继承 BaseActivityClass
private lateinit var startForResult: ActivityResultLauncher<Intent>
private lateinit var timeTextView: TextView
private val handler = Handler(Looper.getMainLooper())
private val updateTimeRunnable = object : Runnable {
override fun run() {
updateTime()
handler.postDelayed(this, 5000) // 每5秒更新一次
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.sixth_layout)
timeTextView = findViewById(R.id.timeTextView)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.timeTextView)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
// 开始定时更新时间
handler.post(updateTimeRunnable)
//点击logoutBtn,退出登录
val logoutBtn: Button = findViewById(R.id.logoutBtn)
logoutBtn.setOnClickListener {
val intent = Intent("com.example.activitytest.FORCE_LOGOUT")
sendBroadcast(intent)
}
}
override fun onDestroy() {
super.onDestroy()
// 停止定时更新
handler.removeCallbacks(updateTimeRunnable)
}
private fun updateTime() {
val currentTime = Calendar.getInstance().time
val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
val formattedTime = "当前时间:${dateFormat.format(currentTime)}"
timeTextView.text = formattedTime
}
}
package com.example.activitytest
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import android.app.AlertDialog
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
open class BaseActivityClass : AppCompatActivity() {
private lateinit var receiver: ForceLogoutReceiver
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//打印当前实例类名
Log.d("BaseActivity", javaClass.simpleName)
ActivityCollector.addActivity(this)
}
override fun onResume() {
super.onResume()
val intentFilter = IntentFilter()
intentFilter.addAction("com.example.activitytest.FORCE_LOGOUT")
receiver = ForceLogoutReceiver()
registerReceiver(receiver, intentFilter)
}
override fun onPause() {
super.onPause()
unregisterReceiver(receiver)
}
override fun onDestroy() {
super.onDestroy()
ActivityCollector.removeActivity(this)
}
inner class ForceLogoutReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
AlertDialog.Builder(context).apply {
setTitle("Warning")
setMessage("You are forced to be logout. Please try to login again.")
setCancelable(false) //不可取消
setPositiveButton("确定") { _, _ ->
ActivityCollector.finishAll() // 销毁所有Activity
val i = Intent(context, LoginActivity::class.java)
context.startActivity(i) // 重新启动LoginActivity
}
show()
}
}
}
}
package com.example.activitytest
import androidx.appcompat.app.AppCompatActivity
object ActivityCollector {
private val activities = ArrayList<AppCompatActivity>()
fun addActivity(activity: AppCompatActivity) {
activities.add(activity)
}
fun removeActivity(activity: AppCompatActivity) {
activities.remove(activity)
}
fun finishAll() {
for (activity in activities) {
if (!activity.isFinishing) {
activity.finish()
}
}
activities.clear()
}
}
package com.example.activitytest
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
class LoginActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
// 其他登录逻辑
}
}
这样修改后,点击 logoutBtn
按钮时,SixthActivity
会发送广播,BaseActivityClass
中的 BroadcastReceiver
会接收到广播并处理强制登出的逻辑。