从前台Service启动的新Activity中按钮无法点击的问题排查
问题:从前台Service启动的Activity按钮无法响应点击
我有一个前台Foreground Service,初始状态下没有任何Activity(已关闭)。点击Service中的按钮会创建并启动Mmap_activity窗口,但该新Activity内的所有按钮均无法响应点击。
前台Service中的点击实现代码
override fun onClick(p0: View?) { if (!moving) { startActivity(Intent(applicationContext, Mmap_activity::class.java) .setAction(Intent.ACTION_VIEW) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) .addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)) } }
Manifest中Mmap_activity的声明
<activity android:name=".Mmap_activity" android:exported="true" android:theme="@style/ActionBarTheme"> <intent-filter> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
activity_mmap.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:layout_width="match_parent" android:layout_height="match_parent" tools:context=".Mmap_activity"> <androidx.constraintlayout.widget.Guideline android:id="@+id/leftBorder" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintGuide_percent=".80" android:orientation="vertical" /> <androidx.constraintlayout.widget.Guideline android:id="@+id/bottomBorder" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent=".10" /> <ImageButton android:id="@+id/mapexitButton" style="@style/Widget.AppCompat.ImageButton" android:layout_width="50dp" android:layout_height="50dp" android:background="#FFFFFF" android:contentDescription="@string/Enter" android:src="@drawable/ic_baseline_close_24" app:layout_constraintBottom_toBottomOf="@id/bottomBorder" app:layout_constraintLeft_toLeftOf="@id/leftBorder" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" tools:ignore="SpeakableTextPresentCheck,DuplicateSpeakableTextCheck" tools:visibility="visible" /> </androidx.constraintlayout.widget.ConstraintLayout>
Mmap_activity的代码
class Mmap_activity : AppCompatActivity() { private lateinit var binding: ActivityMmapBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_mmap) binding = ActivityMmapBinding.inflate(layoutInflater) binding.mapexitButton.setOnClickListener{ println("button pressed") } } }
原因分析
核心问题是Activity视图绑定与布局加载的逻辑冲突:
- 先调用
setContentView(R.layout.activity_mmap)将布局加载到Activity窗口中 - 随后
ActivityMmapBinding.inflate(layoutInflater)创建了一份全新的布局实例,这份实例并未关联到当前Activity的窗口 - 给
binding.mapexitButton设置的点击监听,作用在未显示的布局实例上,而非屏幕上可见的按钮,因此点击无响应
另外,原Manifest中Activity标签存在语法错误(缺少闭合>),布局文件根标签也存在同样问题,这些错误可能导致布局加载异常。
修复方案
以下两种方式任选其一即可:
方式一:通过视图绑定直接加载并设置布局
class Mmap_activity : AppCompatActivity() { private lateinit var binding: ActivityMmapBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 先通过绑定类inflate布局,再将根视图设置为Activity内容视图 binding = ActivityMmapBinding.inflate(layoutInflater) setContentView(binding.root) // 此时绑定的是当前显示的布局,点击监听正常生效 binding.mapexitButton.setOnClickListener{ println("button pressed") } } }
方式二:绑定已加载的布局
class Mmap_activity : AppCompatActivity() { private lateinit var binding: ActivityMmapBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_mmap) // 绑定已经通过setContentView加载到Activity的布局 binding = ActivityMmapBinding.bind(findViewById(android.R.id.content)) binding.mapexitButton.setOnClickListener{ println("button pressed") } } }
额外修正
- 修复Manifest中Activity标签的语法错误(已在上面的代码示例中修正)
- 修复布局文件根标签的语法错误(已在上面的布局代码示例中修正)
内容的提问来源于stack exchange,提问作者Alex97
相关产品推荐
相关产品推荐

