点击Service生成的Notification时已存在的Main Activity重复启动如何解决?
Android Notification点击避免重复启动Activity解决方案
1. 配置Activity启动模式(优先方案)
在AndroidManifest.xml中修改MainActivity的启动模式为singleTask,该模式下如果Activity已经在任务栈中存在,系统会直接复用实例,不会创建新实例:
<activity android:name=".MainActivity" android:launchMode="singleTask" android:exported="true"> <!-- 保留原有的intent-filter等配置 --> </activity>
2. 配置PendingIntent启动参数
构造Notification的跳转Intent时添加对应Flag,避免重复创建实例:
// Java示例 Intent jumpIntent = new Intent(getApplicationContext(), MainActivity.class); // 清除MainActivity上方的所有Activity,复用已存在的MainActivity实例 jumpIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); // 标记是从Notification跳转,可选,用于后续业务逻辑判断 jumpIntent.putExtra("notify_jump", true); PendingIntent contentIntent = PendingIntent.getActivity( getApplicationContext(), 0, jumpIntent, // Android 12及以上必须指定FLAG_IMMUTABLE或FLAG_MUTABLE PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE ); // 将contentIntent设置给Notification的contentIntent属性
3. 实现「应用已存在则通知用户、否则启动」逻辑
如果需要完全符合要求的逻辑,不直接跳转已存在的实例,而是通知用户,可以通过广播中间层实现:
- 第一步:将Notification的PendingIntent改为发送广播,而非直接跳转Activity
Intent notifyIntent = new Intent(this, NotificationClickReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
- 第二步:实现广播接收器,在接收器中判断应用是否已在任务栈中
// Kotlin示例 class NotificationClickReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val am = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager var appExist = false // 遍历运行的任务栈判断当前应用是否已存在 for (task in am.getRunningTasks(100)) { if (task.baseActivity?.packageName == context.packageName) { appExist = true break } } if (appExist) { Toast.makeText(context, "应用已在运行", Toast.LENGTH_SHORT).show() } else { val mainIntent = Intent(context, MainActivity::class.java) mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(mainIntent) } } }
- 第三步:在
AndroidManifest.xml中注册广播接收器
<receiver android:name=".NotificationClickReceiver" android:exported="false"/>
注意:Android 5.0及以上版本获取运行任务栈需要申请
android.permission.GET_TASKS权限,该权限为普通权限,安装时自动授予。
内容的提问来源于stack exchange,提问作者Muhammad Sajid
相关产品推荐
相关产品推荐

