Broadcast Receiver接收广播后启动应用Activity的场景异常问题求助
问题描述
我有两个应用,一个定义了广播接收器(Broadcast Receiver),另一个负责发送广播。
接收方的onReceive()方法代码如下:
@Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Log.i("Started",action); Intent i = null; if(action.equals("LAUNCH_ATTRACTIONS_ACTIVITY")) { i = new Intent(context.getApplicationContext(), MainActivity.class); } else if(action.equals("LAUNCH_HOTELS_ACTIVITY")){ i = new Intent(context.getApplicationContext(), HotelsActivity.class); } context.startActivity(i); }
我在MainActivity中注册Receiver时,为IntentFilter指定了两个Action,代码如下:
intentFilter.addAction("LAUNCH_ATTRACTIONS_ACTIVITY"); intentFilter.addAction("LAUNCH_HOTELS_ACTIVITY"); registerReceiver(myReceiver, intentFilter, "edu.uic.cs478.fall22.mp3", null,RECEIVER_EXPORTED);
发送方发送广播的代码如下:
sendBroadcast(new Intent("LAUNCH_ATTRACTIONS_ACTIVITY"));
现在遇到的问题:先打开接收方应用,再打开发送方应用并点击按钮发送广播,只有当接收方应用是发送方打开前最后运行的应用时,接收方的Activity才会启动。比如打开接收方后回到主屏幕,再打开发送方发广播,Log显示已接收广播,但Activity无法启动;但如果打开接收方后从最近应用列表打开发送方,发广播后接收方的Activity就能正常启动。
接收方Manifest.xml文件:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.example.p3_app2"> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.P3_App2" tools:targetApi="31"> <receiver android:name=".MyReceiver" android:enabled="true" android:exported="true"></receiver> <activity android:name=".HotelsActivity" android:exported="false" /> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
原因分析
核心问题是从BroadcastReceiver中启动Activity时缺少必要的任务栈标记。
BroadcastReceiver的上下文没有关联的任务栈,当尝试启动Activity时:
- 如果接收方应用的任务栈处于前台(比如从最近列表打开发送方,接收方的任务栈还在后台但属于最近活跃状态),系统可以复用现有任务栈启动Activity;
- 如果接收方应用的任务栈已经被切换到后台且不在最近的前台任务链中(比如回到主屏幕后打开新应用),没有指定任务栈标记的话,系统无法为Activity创建新任务栈,导致启动失败。
解决方法
在启动Activity的Intent中添加FLAG_ACTIVITY_NEW_TASK标记,强制系统为Activity创建新的任务栈(或复用已存在的对应应用任务栈)。修改接收方的onReceive()方法:
@Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Log.i("Started",action); Intent i = null; if(action.equals("LAUNCH_ATTRACTIONS_ACTIVITY")) { i = new Intent(context.getApplicationContext(), MainActivity.class); } else if(action.equals("LAUNCH_HOTELS_ACTIVITY")){ i = new Intent(context.getApplicationContext(), HotelsActivity.class); } // 添加任务栈标记 i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(i); }
额外说明:如果希望每次启动都创建新的Activity实例,或复用栈内现有实例,可以根据业务需求添加FLAG_ACTIVITY_CLEAR_TOP或FLAG_ACTIVITY_SINGLE_TOP标记配合使用。
内容的提问来源于stack exchange,提问作者aux
相关产品推荐
相关产品推荐

