Wear OS表盘调用透明Activity:模拟器正常真机停止运行问题咨询
问题原因
- Galaxy Watch4搭载的Wear OS 3(基于One UI Watch)对后台进程管控远严于模拟器:当启动新Activity(哪怕是透明的),系统会将表盘所属的
WatchFaceService判定为非前台进程,触发资源回收机制,直接暂停表盘绘制逻辑并释放相关资源,导致表盘图形消失。 Intent.FLAG_ACTIVITY_NEW_TASK会创建独立任务栈,进一步让系统判定原表盘任务已处于后台,加速其被回收的进程,而模拟器通常没有严格的后台限制,因此不会出现该问题。
解决方案
方案1:用悬浮窗(Overlay)替代透明Activity(推荐)
悬浮窗不属于Activity范畴,不会抢占前台进程优先级,能保证表盘持续运行,步骤如下:
- 在
AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
- 动态申请悬浮窗权限(Android 6.0+):
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(context)) { val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:${context.packageName}")) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(intent) }
- 创建并显示悬浮窗:
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager val params = WindowManager.LayoutParams().apply { type = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY } else { WindowManager.LayoutParams.TYPE_SYSTEM_ALERT } flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN width = WindowManager.LayoutParams.WRAP_CONTENT height = WindowManager.LayoutParams.WRAP_CONTENT format = PixelFormat.TRANSLUCENT gravity = Gravity.CENTER } val overlayView = LayoutInflater.from(context).inflate(R.layout.your_transparent_layout, null) windowManager.addView(overlayView, params)
不需要悬浮窗时记得移除:windowManager.removeView(overlayView)
方案2:调整透明Activity配置(不推荐,仍可能受系统限制)
如果必须使用Activity,可通过以下配置降低被系统回收的概率:
- 在
AndroidManifest.xml中配置Activity:
<activity android:name=".MyActivity" android:theme="@style/Theme.Transparent" android:launchMode="singleInstance" android:excludeFromRecents="true" android:taskAffinity="" android:noHistory="true"> </activity>
- 修改启动Intent的Flag:
val intent = Intent(context, MyActivity::class.java) intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_NO_HISTORY or Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS context.startActivity(intent)
- 在Activity中保持唤醒状态,避免系统休眠回收:
private lateinit var wakeLock: PowerManager.WakeLock override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyApp::WatchFaceWakeLock") wakeLock.acquire(10*60*1000L /*10分钟*/) } override fun onDestroy() { super.onDestroy() if (wakeLock.isHeld) { wakeLock.release() } }
同时在Manifest中添加WAKE_LOCK权限:
<uses-permission android:name="android.permission.WAKE_LOCK" />
内容的提问来源于stack exchange,提问作者go3d
相关产品推荐
相关产品推荐

