You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加FLAG_NOT_FOCUSABLE后返回键触发ANR,求AppLocker返回功能实现方案

Fixing the ANR Issue & Implementing AppLocker-Style Back Key Behavior

Hey there! Let's break down your problem and build a solid solution for your AppLocker-like feature. First off, that FLAG_NOT_FOCUSABLE you added is the root cause of your ANR—here's why and how to fix it, plus a way to meet your core requirement.

Why FLAG_NOT_FOCUSABLE Triggers ANR

When you set this flag on your Activity, it loses the ability to receive input focus. When you press the back key, the system tries to route the event to a focused window—but since your Activity can't hold focus, the system gets stuck waiting for a valid target. This blocks the main thread for over 5 seconds, which is exactly what triggers the ANR you're seeing. The first fix is straightforward: remove this flag entirely.

Solution Overview

We’ll create a custom back key handler that:

  1. Eliminates the focus-related ANR by ditching FLAG_NOT_FOCUSABLE
  2. Clears your app’s background Activities
  3. Handles other apps’ Activities (with adjustments for Android’s security rules)

Step 1: Remove the Troublesome Flag

Update your Activity code to remove the focus flag:

public class MainActivity extends AppCompatActivity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_main); 
        // Delete this line completely:
        // getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE); 
    } 
}

Step 2: Implement Custom Back Key Handling

Override onBackPressed() (or use OnBackPressedCallback for modern AndroidX apps) to control what happens when the back key is pressed. We’ll add logic to clear background Activities before finishing the current one.

Option 1: Traditional onBackPressed() Override

@Override
public void onBackPressed() {
    // Clear background Activities first
    clearBackgroundActivities();
    // Then finish the current Activity
    super.onBackPressed();
}

For apps using AndroidX, this is the cleaner approach:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Register back key callback
    getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
        @Override
        public void handleOnBackPressed() {
            clearBackgroundActivities();
            // Finish current Activity and clean up the callback
            finish();
            remove();
        }
    });
}

Step 3: Clear Your App’s Background Activities

To close other Activities in your app, maintain a global Activity stack to track all running instances. Here’s a simple singleton manager for this:

Activity Stack Manager Singleton

public class ActivityStackManager {
    private static ActivityStackManager instance;
    private final Stack<Activity> activityStack;

    private ActivityStackManager() {
        activityStack = new Stack<>();
    }

    public static synchronized ActivityStackManager getInstance() {
        if (instance == null) {
            instance = new ActivityStackManager();
        }
        return instance;
    }

    // Call this in every Activity's onCreate()
    public void addActivity(Activity activity) {
        activityStack.add(activity);
    }

    // Call this in every Activity's onDestroy()
    public void removeActivity(Activity activity) {
        activityStack.remove(activity);
    }

    // Close all app Activities except the current one
    public void finishAllExceptCurrent(Activity currentActivity) {
        for (Activity activity : activityStack) {
            if (activity != currentActivity && !activity.isFinishing()) {
                activity.finish();
            }
        }
    }
}

Integrate the Manager into Your Activities

In every Activity’s onCreate():

ActivityStackManager.getInstance().addActivity(this);

In every Activity’s onDestroy():

ActivityStackManager.getInstance().removeActivity(this);

Step 4: Handle Other Apps’ Activities

Android’s security model restricts regular apps from directly closing other apps’ Activities. Here are your options:

For Regular Consumer Apps

The best approach is to send the user back to the home screen, which moves all background apps out of view (they won’t be finished, but they’ll be sent to the background):

private void clearBackgroundActivities() {
    // Close your app's background Activities
    ActivityStackManager.getInstance().finishAllExceptCurrent(this);

    // Send user to the home screen
    Intent homeIntent = new Intent(Intent.ACTION_MAIN);
    homeIntent.addCategory(Intent.CATEGORY_HOME);
    homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(homeIntent);
}

For System-Level Apps (With Special Permissions)

If your app is signed with the system signature or has system-level permissions, you can force-stop other apps:

  1. Add the permission to your AndroidManifest.xml:
    <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES"
        tools:ignore="ProtectedPermissions" />
    
  2. Implement the force-stop logic:
    private void forceStopOtherApps() {
        ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> runningApps = am.getRunningAppProcesses();
        for (ActivityManager.RunningAppProcessInfo appInfo : runningApps) {
            // Skip your own app
            if (!appInfo.processName.equals(getPackageName())) {
                am.forceStopPackage(appInfo.processName);
            }
        }
    }
    

Final Notes

  • The FORCE_STOP_PACKAGES permission is restricted to system apps—regular consumer apps can’t use it, so stick to the home screen approach for most use cases.
  • Test edge cases: Ensure your Activity stack manager handles configuration changes (like screen rotations) by updating the stack when Activities are recreated.

内容的提问来源于stack exchange,提问作者Baskya Visuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 03:59:53