android程序卡死无响应,防止android应用程序无响应ANR(Application Not Responding)

本文围绕Android应用无响应(ANR)问题展开。介绍了ANR的定义、三种类型,如按键或触摸事件无响应等。阐述避免KeyDispatchTimeout的方法,如UI线程只做UI相关工作。还说明了如何分析ANR,可通过LOG和trace.txt文件,同时介绍了StrictMode工具用于检测主线程操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在android中应用被单个线程操作:主线程,或者叫做UI线程。

一:什么是ANR

ANR:Application Not Responding,即应用无响应

二:ANR的类型

ANR一般有三种类型:

1:KeyDispatchTimeout(5 seconds) --主要类型

按键或触摸事件在特定时间内无响应

2:BroadcastTimeout(10 seconds)

BroadcastReceiver在特定时间内无法处理完成

3:ServiceTimeout(20 seconds) --小概率类型

Service在特定的时间内无法处理完成

五:如何避免KeyDispatchTimeout

1:UI线程尽量只做跟UI相关的工作

2:耗时的工作(比如数据库操作,I/O,连接网络或者别的有可能阻碍UI线程的操作)把它放入单独的线程处理

3:尽量用Handler来处理UIthread和别的thread之间的交互

六:UI线程

说了那么多的UI线程,那么哪些属于UI线程呢?

UI线程主要包括如下:

Activity:onCreate(), onResume(), onDestroy(), onKeyDown(), onClick(),etc

AsyncTask: onPreExecute(), onProgressUpdate(), onPostExecute(), onCancel,etc

Mainthread handler: handleMessage(), post*(runnable r), etc

other

七:如何去分析ANR

先看个LOG:

04-01 13:12:11.572I/InputDispatcher( 220): Application is not responding:Window{2b263310com.android.email/com.android.email.activity.SplitScreenActivitypaused=false}.

5009.8ms since event, 5009.5ms since waitstarted

04-0113:12:11.572 I/WindowManager( 220): Input event dispatching timedout sending tocom.android.email/com.android.email.activity.SplitScreenActivity

04-0113:12:14.123 I/Process(  220): Sending signal. PID: 21404 SIG: 3---发生ANR的时间和生成trace.txt的时间

04-01 13:12:14.123 I/dalvikvm(21404):threadid=4: reacting to signal 3

……

04-0113:12:15.872 E/ActivityManager(  220): ANR in com.android.email(com.android.email/.activity.SplitScreenActivity)

04-0113:12:15.872 E/ActivityManager(  220): Reason:keyDispatchingTimedOut

04-0113:12:15.872 E/ActivityManager(  220): Load: 8.68 / 8.37 / 8.53

04-0113:12:15.872 E/ActivityManager(  220):CPUusage from 4361ms to 699ms ago----CPU在ANR发生前的使用情况

04-0113:12:15.872 E/ActivityManager(  220):   5.5%21404/com.android.email: 1.3% user + 4.1% kernel / faults: 10 minor

04-0113:12:15.872 E/ActivityManager(  220):   4.3%220/system_server: 2.7% user + 1.5% kernel / faults: 11 minor 2 major

04-0113:12:15.872 E/ActivityManager(  220):   0.9%52/spi_qsd.0: 0% user + 0.9% kernel

04-0113:12:15.872 E/ActivityManager(  220):   0.5%65/irq/170-cyttsp-: 0% user + 0.5% kernel

04-0113:12:15.872 E/ActivityManager(  220):   0.5%296/com.android.systemui: 0.5% user + 0% kernel

04-0113:12:15.872 E/ActivityManager(  220):100%TOTAL: 4.8% user + 7.6% kernel + 87% iowait

04-0113:12:15.872 E/ActivityManager(  220):CPUusage from 3697ms to 4223ms later:--

ANR后CPU的使用量

04-0113:12:15.872 E/ActivityManager(  220):   25%21404/com.android.email: 25% user + 0% kernel / faults: 191 minor

04-0113:12:15.872 E/ActivityManager(  220):    16% 21603/__eas(par.hakan: 16% user + 0% kernel

04-0113:12:15.872 E/ActivityManager(  220):    7.2% 21406/GC: 7.2% user + 0% kernel

04-0113:12:15.872 E/ActivityManager(  220):    1.8% 21409/Compiler: 1.8% user + 0% kernel

04-0113:12:15.872 E/ActivityManager(  220):   5.5%220/system_server: 0% user + 5.5% kernel / faults: 1 minor

04-0113:12:15.872 E/ActivityManager(  220):    5.5% 263/InputDispatcher: 0% user + 5.5% kernel

04-0113:12:15.872 E/ActivityManager(  220):32%TOTAL: 28% user + 3.7% kernel

从LOG可以看出ANR的类型,CPU的使用情况,如果CPU使用量接近100%,说明当前设备很忙,有可能是CPU饥饿导致了ANR

如果CPU使用量很少,说明主线程被BLOCK了

如果IOwait很高,说明ANR有可能是主线程在进行I/O操作造成的

除了看LOG,解决ANR还得需要trace.txt文件,

如何获取呢?可以用如下命令获取

$chmod 777 /data/anr

$rm /data/anr/traces.txt

$ps

$kill -3 PID

adbpull data/anr/traces.txt ./mytraces.txt

从trace.txt文件,看到最多的是如下的信息:

-----pid 21404 at 2011-04-01 13:12:14 -----

Cmdline: com.android.email

DALVIK THREADS:

(mutexes: tll=0tsl=0 tscl=0 ghl=0 hwl=0 hwll=0)

"main" prio=5 tid=1NATIVE

| group="main" sCount=1 dsCount=0obj=0x2aad2248 self=0xcf70

| sysTid=21404 nice=0 sched=0/0cgrp=[fopen-error:2] handle=1876218976

atandroid.os.MessageQueue.nativePollOnce(Native Method)

atandroid.os.MessageQueue.next(MessageQueue.java:119)

atandroid.os.Looper.loop(Looper.java:110)

at android.app.ActivityThread.main(ActivityThread.java:3688)

at java.lang.reflect.Method.invokeNative(Native Method)

atjava.lang.reflect.Method.invoke(Method.java:507)

atcom.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)

at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:624)

at dalvik.system.NativeStart.main(Native Method)

说明主线程在等待下条消息进入消息队列

七:STRICTMODE

这个工具会检测发生在主线程上的磁盘或者网络操作并且会采取行动来警告开发者(包括日志记录和应用程序崩溃)

StrictMode.setThreadPolicy(new StrictMode.VmPolicy.Builder()

.detectAll()

.penaltyLog()

.penaltyDialog()

.build());(monitor specific thread)

StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()

.detectAll()

.penaltyLog()

.penaltyDeath()

.build());(monitor all threads)

只在调试模式下启动StrictMode

如何检测:

public class Util {

public static boolean isDebugMode(Context context) {

PackageManager pm = context.getPackageManager();

try {

ApplicationInfo info = pm.getApplicationInfo(context.getPackageName(), 0);

return (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;

} catch (NameNotFoundException e) {

}

return true;

}

public static boolean useStrictMode(Context context) {

return isDebugMode(context) && Build.VERSIONSDK_INT >= 9;

}

}

<think>嗯,用户问的是当应用程序提示“没有响应”时,如何通过日志来查看问题。首先,我需要理解用户的需求。他们可能遇到了应用程序卡死或者无响应的情况,想要通过日志来诊断原因。接下来,我需要考虑不同的操作系统,比如Windows、Linux、Android和macOS,因为日志的位置和查看方法可能不同。 首先,Windows系统。用户可能需要查看事件查看器,特别是应用程序日志。这里需要指导他们如何打开事件查看器,找到对应的错误或警告事件。另外,如果是特定应用程序的日志,可能需要到ProgramData下的文件夹查找。 然后是Linux系统,通常日志存放在/var/log目录下,比如syslog或应用程序专属的日志文件。可能需要用tail或grep命令来实时查看或过滤日志中的错误信息。 Android方面,可以通过Android Studio的Logcat或者ADB命令来获取日志,特别是要过滤ANRApplication Not Responding)相关的日志,这些通常存放在/data/anr目录下,但需要root权限才能访问。 macOS的话,控制台应用是查看系统日志和崩溃报告的地方,同时用户目录下的日志和~/Library/Logs也是关键位置。 另外,还需要考虑通用方法,比如应用程序自身的日志配置,或者第三方日志工具。在分析日志时,要关注错误堆栈、时间戳和资源使用情况,比如内存或CPU的高占用可能导致无响应。 需要确保步骤清晰,分点说明不同系统的操作方法,同时提醒用户注意权限问题,比如需要管理员权限或开启调试模式。可能还需要解释一些术语,比如ANR,确保用户理解。最后,给出分析日志时的关键点,帮助他们快速定位问题。</think>当应用程序提示“没有响应”时,通过日志排查问题可按照以下步骤进行: --- ### **一、定位日志文件** #### 1. **系统日志** - **Windows** - 打开 **事件查看器** (`eventvwr.msc`) - 路径:`Windows 日志 > 应用程序` - 筛选 `错误` 或 `警告` 事件,检查对应时间戳的应用程序崩溃记录 - **Linux** - 系统日志路径:`/var/log/syslog` 或 `/var/log/messages` - 使用命令实时监控日志: ```bash tail -f /var/log/syslog | grep "应用程序名" ``` - **macOS** - 打开 **控制台** 应用 (`Console.app`) - 查看 `系统日志` 或 `崩溃报告`,过滤相关应用程序名称 #### 2. **应用程序专属日志** - 路径可能包含: - Windows: `C:\ProgramData\应用程序名\logs` - Linux/macOS: `/var/log/应用程序名` 或 `~/Library/Logs` (macOS) - 移动端(Android/iOS):通过开发工具(Android Studio/Xcode)导出日志 #### 3. **崩溃转储文件** - Windows: `.dmp` 文件(需调试工具如 WinDbg 分析) - Linux: `core dump` 文件(需配置 `ulimit` 并分析) --- ### **二、关键日志分析点** 1. **错误堆栈(Stack Trace)** - 查找 `Exception`、`Error`、`Segmentation fault` 等关键词,定位崩溃代码位置 - 示例: ``` java.lang.NullPointerException: Attempt to invoke virtual method on null object at com.example.app.MainActivity.onCreate(MainActivity.java:42) ``` 2. **资源占用记录** - 检查日志中是否包含 `内存不足`、`CPU 占用超限` 等提示 - Linux 示例: ``` Out of memory: Kill process 1234 (app_name) score 999 ``` 3. **第三方依赖问题** - 数据库连接失败:`SQLException: Connection refused` - 网络超时:`SocketTimeoutException` --- ### **三、高级排查工具** 1. **实时监控工具** - Windows: `Process Explorer` 查看线程状态 - Linux: `strace -p 进程ID` 跟踪系统调用 2. **Android ANR 日志** - 路径:`/data/anr/traces.txt`(需 root 权限) - 通过 `adb` 导出: ```bash adb pull /data/anr/traces.txt ``` --- ### **四、常见原因总结** | 问题类型 | 日志特征 | 解决方案 | |-------------------|----------------------------------|--------------------------| | 主线程阻塞 | `ANR in com.example.app` | 优化耗时操作到子线程 | | 内存泄漏 | `GC Overhead Limit Exceeded` | 使用分析工具(如MAT) | | 死锁 | `Thread-1 waiting for lock 0x...`| 检查同步代码块 | --- ### **五、操作注意事项** - **权限问题**:Linux/macOS 需 `sudo` 访问系统日志 - **时间同步**:确保系统时间与日志时间戳一致 - **日志级别**:临时调高日志级别(如DEBUG)以获取更多信息 通过以上步骤,可逐步定位应用程序无响应的根本原因。若日志信息不足,建议结合代码调试工具(如GDB、Visual Studio Debugger)进一步分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值