In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article introduces the relevant knowledge of "what is the principle of Android ANR". In the operation of actual cases, many people will encounter such a dilemma. Then let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
I. brief introduction of ANR description and reason 1.1
The full name of ANR: Application Not Responding, that is, the application is unresponsive.
1.2 reasons
In Android system, ActivityManagerService (referred to as AMS) and WindowManagerService (referred to as WMS) will detect the response time of App. If the App cannot correspond to the screen touch or keyboard input time at a specific time, or if a specific event has not been handled, ANR will appear.
The following four conditions can cause ANR to occur:
InputDispatching Timeout:5 cannot respond to screen touch events or keyboard input events within seconds
BroadcastQueue Timeout: when executing the onReceive () function of the foreground broadcast (BroadcastReceiver), the processing is not completed in 10 seconds, and 60 seconds in the background.
Service Timeout: the foreground service is not completed within 20 seconds, but the backend service is not completed within 200 seconds.
ContentProvider Timeout: the publish of ContentProvider was not finished in 10 seconds.
1.3 avoid
Try to avoid time-consuming operations in the main thread (UI thread).
Then the time-consuming operation is placed in the child thread.
II. ANR analysis method 2.1ANR reappearance
The test here is done by Google Pixel xl (Android 8.0 system), which is called Google's own son, and generates a button to jump to ANRTestActivity, where the main thread sleeps for 20 seconds in onCreate ():
@ Overrideprotected void onCreate (@ Nullable Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_anr_test); / / this is the thread sleep function provided by Android. The biggest difference from Thread.sleep () is that / / this function will not throw an InterruptedException exception. SystemClock.sleep (20 * 1000);}
After entering ANRTestActivity, the screen went black for a period of time, about seven or eight seconds, and finally the ANR exception popped up.
2.2 ANR analysis method 1: Log
After generating ANR just now, take a look at Log:
You can see that logcat clearly records when the ANR occurs, as well as the thread's tid and a sentence that summarizes the reason: WaitingInMainSignalCatcherLoop, which roughly means that the main thread waits for an exception.
The last sentence is The application may be doing too much work on its main thread. Tells you that too much work may have been done on the main thread.
2.3The second method of ANR analysis: traces.txt
The second sentence Wrote stack traces to'/ data/anr/traces.txt', in log just now indicates that the ANR exception has been exported to the traces.txt file. Use the adb command to export this file from the phone:
1.cd to the directory where adb.exe is located, that is, the platform-tools directory of Android SDK, for example:
Cd D:\ Android\ AndroidSdk\ platform-tools
In addition, in addition to Windows's cmd, you can also use AndroidStudio's Terminal to enter adb commands.
two。 After going to the specified directory, execute the following adb command to export the traces.txt file:
Adb pull / data/anr/traces.txt
Traces.txt is exported by default to the\ platform-tools directory of Android SDK. Generally speaking, traces.txt files record a lot of things, so we need to find relevant records pertinently when analyzing.
-pid 23346 at 2017-11-07 11:33:57-> process id and ANR generation time Cmd line: com.sky.myjavatestBuild fingerprint: 'google/marlin/marlin:8.0.0/OPR3.170623.007/4286350:user/release-keys'ABI:' arm64'Build type: optimizedZygote loaded classes=4681 post zygote classes=106Intern table: 42675 strong; 137 weakJNI: CheckJNI is on Globals=526 (plus 22 weak) Libraries: / system/lib64/libandroid.so / system/lib64/libcompiler_rt.so / system/lib64/libjavacrypto.so/system/lib64/libjnigraphics.so / system/lib64/libmedia_jni.so / system/lib64/libsoundpool.so/system/lib64/libwebviewchromium_loader.so libjavacore.so libopenjdk.so (9) Heap: 22% free, 1478KB/1896KB 21881 objects-> memory usage... "main" prio=5 tid=1 Sleeping-> reason is Sleeping | group= "main" sCount=1 dsCount=0 flags=1 obj=0x733d0670 self=0x74a4abea00 | sysTid=23346 nice=-10 cgrp=default sched=0/0 handle=0x74a91ab9b0 | state=S schedstat= (391462128 82838177) utm=33 stm=4 core=3 HZ=100 | stack=0x7fe6fac000-0x7fe6fae000 stackSize=8MB | held mutexes= at java.lang.Thread.sleep (Native method)-sleeping on (a java.lang.Object) at java.lang.Thread.sleep (Thread.java:373)-locked (a java.lang.Object) at java.lang.Thread.sleep (Thread.java:314) at android.os.SystemClock.sleep (SystemClock.java:122) at com.sky.myjavatest.ANRTestActivity.onCreate (ANRTestActivity.java:20)-> the name of the package that produces ANR and the specific number of lines at android.app.Activity.performCreate (Activity.java:6975) at android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1213) at android.app.ActivityThread.performLaunchActivity (ActivityThread. Java:2770) at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2892) at android.app.ActivityThread.-wrap11 (ActivityThread.java:-1) at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1593) at android.os.Handler.dispatchMessage (Handler.java:105) at android.os.Looper.loop (Looper.java:164) at android.app.ActivityThread.main (ActivityThread.java:6541) at java.lang.reflect.Method.invoke (Native method) at com .android.room.os.Zygote $MethodAndArgsCaller.run (Zygote.java:240) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:767)
Use ctrl + F to find the package name in the file to quickly locate the relevant code.
The related problems can be seen from the log above:
Process id and package name: pid 23346 com.sky.myjavatest
The cause of ANR: Sleeping
The specific number of lines causing the ANR: line 20 of the ANRTestActivity.java:20 class
Special note: generate a new ANR and the original traces.txt file will be overwritten.
2.4 ANR analysis method 3: Java thread call analysis
The commands provided by JDK can help analyze and debug Java applications. The commands are:
Jstack {pid}
Where pid can be obtained through the jps command, which lists all Java virtual machine processes running on the current system, such as
7266 Test7267 Jps2.5 ANR analysis method 4: DDMS analysis of ANR problem
Use the DDMS--Update Threads tool
Read the output of Update Threads
III. The causes of ANR and its solutions
The above example is only an ANR caused by a simple time-consuming operation of the main thread, and there are many other reasons for ANR:
Main thread blocking or main thread data reading
Solution: avoid deadlocks and use child threads to handle time-consuming operations or blocking tasks. Try to avoid query provider in the main thread and do not abuse SharePreferenceS
CPU is at full load, Imax O is blocked
Solution: file read and write or database operations are placed in child thread asynchronous operations.
Insufficient memory
Solution: android:largeHeap= "true" can be set in the AndroidManifest.xml file to increase the memory used by App. However, it is not recommended to use this method, fundamentally prevent memory leaks, optimize memory use is the right way.
Each major component ANR
Time-consuming operations should also be avoided during the lifecycle of major components, and note that the onRecieve (), background Service, and ContentProvider of BroadcastReciever do not perform tasks for too long.
4. ANR source code analysis of Service Timeout caused by 4.1 Service
Service Timeout is triggered when an AMS.MainHandler in the "ActivityManager" thread receives a SERVICE_TIMEOUT_MSG message.
4.1.1 sending delay messages
RealStartServiceLocked is called from the Service process attach to the system_server process, followed by mAm.mHandler.sendMessageAtTime () to send a delay message, which is often defined, such as 20 seconds for the foreground Service. Triggered when an AMS.MainHandler in the ActivityManager thread receives a SERVICE_TIMEOUT_MSG message.
AS.realStartServiceLocked
ActiveServices.java
Private final void realStartServiceLocked (ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException {. / / send delay message (SERVICE_TIMEOUT_MSG) bumpServiceExecutingLocked (r, execInFg, "create") Try {. / / the onCreate () method app.thread.scheduleCreateService (r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked (r.serviceInfo.applicationInfo), app.repProcState) of try {/ / final execution of the service;} catch (DeadObjectException e) {mAm.appDiedLocked (app); throw e;} finally {...}}
AS.bumpServiceExecutingLocked
Private final void bumpServiceExecutingLocked (ServiceRecord r, boolean fg, String why) {... ScheduleServiceTimeoutLocked (r.app);} void scheduleServiceTimeoutLocked (ProcessRecord proc) {if (proc.executingServices.size () = = 0 | | proc.thread = = null) {return;} long now = SystemClock.uptimeMillis (); Message msg = mAm.mHandler.obtainMessage (ActivityManagerService.SERVICE_TIMEOUT_MSG); msg.obj = proc / / if there is still no remove for the SERVICE_TIMEOUT_MSG message after the timeout, the service Timeout process mAm.mHandler.sendMessageAtTime (msg, proc.execServicesFg? (now+SERVICE_TIMEOUT): (now+SERVICE_ BACKGROUND_TIMEOUT);}
4.1.2 the main thread that enters the target process creates a Service
The main thread handleCreateService (CreateServiceData data) that enters the target process through layers of calls such as Binder.
ActivityThread.java
Private void handleCreateService (CreateServiceData data) {... Java.lang.ClassLoader cl = packageInfo.getClassLoader (); Service service = (Service) cl.loadClass (data.info.name). NewInstance (); Try {/ / create ContextImpl object ContextImpl context = ContextImpl.createAppContext (this, packageInfo); context.setOuterContext (service); / / create Application object Application app = packageInfo.makeApplication (false, mInstrumentation); service.attach (context, this, data.info.name, data.token, app, ActivityManagerNative.getDefault ()) / / call the service onCreate () method service.onCreate (); / / cancel the delay message ActivityManagerNative.getDefault (). ServiceDoneExecuting (data.token, SERVICE_DONE_EXECUTING_ANON, 0,0) of AMS.MainHandler;} catch (Exception e) {.}}
This method creates the target service object, calls back the commonly used Service's onCreate () method, and then returns to system_server via serviceDoneExecuting () to execute the delay message to cancel the AMS.MainHandler.
4.1.3 back to system_server to execute the delay message of canceling AMS.MainHandler
AS.serviceDoneExecutingLocked
Private void serviceDoneExecutingLocked (ServiceRecord r, boolean inDestroying, boolean finishing) {... If (r.executeNesting 0) {long now = SystemClock.uptimeMillis (); if ((numReceivers > 0) & & (now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers) {/ / step 1\. Sends a delay message, which handles a lot of things, such as broadcast processing timeout ending broadcast broadcastTimeoutLocked (false) ...} if (r.receivers = = null | | r.nextReceiver > = numReceivers | | r.resultAbort | | forceReceive) {if (r.resultTo! = null) {/ / 2\. Deal with broadcast message performReceiveLocked (r.callerApp, r.resultTo, new Intent (r.intent), r.resultCode, r.resultData, r.resultExtras, false, false, r.userId); r.resultTo = null;} / / 3\. Cancel broadcast timeout ANR message cancelBroadcastTimeoutLocked ();}} while (r = = null);... / get the next ordered broadcast r.receiverTime = SystemClock.uptimeMillis (); if (! mPendingBroadcastTimeoutMessage) {long timeoutTime = r.receiverTime + mTimeoutPeriod; / / set broadcast timeout setBroadcastTimeoutLocked (timeoutTime) }...}}
The step 1. BroadcastTimeoutLocked (false) function above: records time information and calls the function to set up sending delay messages
Final void broadcastTimeoutLocked (boolean fromMsg) {... Long now = SystemClock.uptimeMillis (); if (fromMsg) {if (mService.mDidDexOpt) {/ / Delay timeouts until dexopt finishes. MService.mDidDexOpt = false; long timeoutTime = SystemClock.uptimeMillis () + mTimeoutPeriod; setBroadcastTimeoutLocked (timeoutTime); return;} if (! mService.mProcessesReady) {return;} long timeoutTime = r.receiverTime + mTimeoutPeriod If (timeoutTime > now) {/ / step 2 setBroadcastTimeoutLocked (timeoutTime); return;}}
The step 2.setBroadcastTimeoutLocked function above: sets the specific operation of broadcast timeout, and also sends delay messages
Final void setBroadcastTimeoutLocked (long timeoutTime) {if (! MPendingBroadcastTimeoutMessage) {Message msg = mHandler.obtainMessage (BROADCAST_TIMEOUT_MSG, this); mHandler.sendMessageAtTime (msg, timeoutTime); mPendingBroadcastTimeoutMessage = true;}}
4.2.2 the parameter timeoutTime of the setBroadcastTimeoutLocked (long timeoutTime) function is the current time plus the set timeout.
That is, above.
Long timeoutTime = SystemClock.uptimeMillis () + mTimeoutPeriod
MTimeoutPeriod is 10s of the foreground queue and 60s of the background queue.
Public ActivityManagerService (Context systemContext) {... Static final int BROADCAST_FG_TIMEOUT = 10 * 1000; static final int BROADCAST_BG_TIMEOUT = 60 * 1000; MFgBroadcastQueue = new BroadcastQueue (this, mHandler, "foreground", BROADCAST_FG_TIMEOUT, false); mBgBroadcastQueue = new BroadcastQueue (this, mHandler, "background", BROADCAST_BG_TIMEOUT, true);...}
4.2.3 call cancelBroadcastTimeoutLocked after performReceiveLocked is executed in the processNextBroadcast () procedure
CancelBroadcastTimeoutLocked: when performReceiveLocked () in the broadcast message processing function processNextBroadcast () has finished processing the broadcast message, call cancelBroadcastTimeoutLocked () to cancel the timeout message.
Final void cancelBroadcastTimeoutLocked () {if (mPendingBroadcastTimeoutMessage) {mHandler.removeMessages (BROADCAST_TIMEOUT_MSG, this); mPendingBroadcastTimeoutMessage = false;}} 4.3 ContentProvider ContentProvider Timeout
ContentProvider Timeout is triggered when an AMS.MainHandler in the "ActivityManager" thread receives a CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG message.
5. Information collection of Android ANR
The AMS.appNotResponding () method is eventually called whenever ANR occurs in any of the four major components or processes.
This is the end of the content of "what is the principle of Android ANR"? thank you for your reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.