Android - 强制应用无响应以进行测试目的

14
我为什么无法使用此代码强制触发Android ANR? 没有日志消息或弹出窗口。应用程序只是懒惰地启动。
[更新]
即使睡眠View.setOnClickListener或BroadcastReceiver.onReceive,我也无法获得它!
有什么诀窍吗?
public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            Log.e("Test", "", e);
        }
    }
}

“我正在使用带有原生Android 3.2的三星GT-6200L。”

可能onCreate方法还没有在UI线程上运行,可以尝试在onStart或onResume方法中添加sleep。 - Marcio Covre
@nininho onCreate 不能不在 UI 线程上。 - olshevski
1
在Android 4.0中,开发者有一个选项 - “显示所有ANR”或类似选项。也许你在Android 3.2上有这样的选项?它默认是关闭的,所以普通用户不会受到干扰。 - olshevski
非常奇怪...即使在View.setOnClickListener或BroadcastReceiver.onReceive中睡觉,我也无法理解它... - CelinHC
@Kzinch 我在ICS/JellyBeans中的设置>开发者选项中看到了这一点。不幸的是,在3.2中没有这个选项,至少在三星GT-6200中没有... - CelinHC
6个回答

13

尝试在 onTouchEvent 中使用。在 onCreate 中,您的活动尚未完全运行。

@Override
public boolean onTouchEvent(MotionEvent event) {
    Log.d(TAG,"onTouchEvent");  
    while(true) {}
}

请确保这个程序能够正常运行。Thread.sleep总是会被执行,除非它被中断(你可以通过logcat消息来检查),否则它将会阻塞程序,如果程序在3秒内没有响应任何回调,Android将会抛出ANR异常。 - NikkyD
@CelinHC 当主线程上没有其他操作时,你不会立即看到 ANR 弹出。你必须等待它或者通过按下返回按钮并等待几秒钟来触发它。 - Albert-Jan Verhees
@Albert-JanVerhees 这可能是我长期以来期待的答案。我会测试它。 - CelinHC
因为Android会给应用程序很多时间来处理工作,如果没有需要响应的内容(直到达到阈值),但是如果需要响应某些内容而应用程序没有响应,则会抛出ANR异常。 - NikkyD

5
ANR-WatchDog 项目提供了一个测试应用程序,可以可靠地(就 ANR 而言)产生 ANR:该应用程序由于死锁而挂起。
简言之:
  1. Prepare a lock object as a private field in your activity: final Object mutex = new Object();

  2. Have a thread that performs some work in a critical section, and an android.os.Handler that posts work depending on the same lock.

    new Thread(new Runnable() {
      @Override
      public void run() {
        synchronized (mutex) {
          while (true) {
            try {
               Thread.sleep(60000);
            }
            catch (InterruptedException e) {
              e.printStackTrace();
            }
          }
        }
      }
    }).start();
    
    new Handler().postDelayed(new Runnable() {
      @Override
      public void run() {
        synchronized (mutex) {
          // Shouldn't happen
          throw new IllegalStateException();
        }
      }
    }, 1000);
    
将上述代码片段放在按钮单击处理程序中,例如,应该就可以解决问题。

3

尝试使用以下方法:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    int a=0;
    while(true) {
        a++;
    }       
}

你的代码可能没有工作是因为它被设置得太早了,而活动可能还没有完全初始化和创建。使用上述代码启动活动,触摸/滑动屏幕并等待ANR对话框弹出。


真的吗?我在我的设备上试过了,它运行得非常好。 - Raghav Sood

3
我昨天遇到了同样的问题,发现使用普通的调试版本时,ANR对话框根本不会弹出。(尽管UI线程完全挂起。)

但是,在导出并正确签名应用程序后,对话框可以正常弹出(在上述所有情况下)。然而,我仍然不确定是什么阻止了ANR消息的弹出,也许其他人以后可以澄清这一点...

如果您在设备设置中开启了开发者选项,它们将会显示出来。 - alla

1
在你的活动中创建一个按钮。
public void onBtn1(View v) {
   int a = 0;
   while(true) {
      a++;
   }
}

让按钮执行上面的代码。 用手指疯狂点击按钮 =)


0

我使用这段代码强制 ANR

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

    public void force(View view){
        while(true) {}
    }

我刚在 XML 文件中创建了一个简单的按钮,并设置了 android:onClick=force

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接