<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                #### 15.1.4 響應速度優化和ANR日志分析 響應速度優化的核心思想是避免在主線程中做耗時操作,但是有時候的確有很多耗時操作,怎么辦呢?可以將這些耗時操作放在線程中去執行,即采用異步的方式執行耗時操作。響應速度過慢更多地體現在Activity的啟動速度上面,如果在主線程中做太多事情,會導致Activity啟動時出現黑屏現象,甚至出現ANR。Android規定,Activity如果5秒鐘之內無法響應屏幕觸摸事件或者鍵盤輸入事件就會出現ANR,而BroadcastReceiver如果10秒鐘之內還未執行完操作也會出現ANR。在實際開發中,ANR是很難從代碼上發現的,如果在開發過程中遇到了ANR,那么怎么定位問題呢?其實當一個進程發生ANR了以后,系統會在/data/anr目錄下創建一個文件traces.txt,通過分析這個文件就能定位出ANR的原因,下面模擬一個ANR的場景。下面的代碼在Activity的onCreate中休眠30s,程序運行后持續點擊屏幕,應用一定會出現ANR: protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); SystemClock.sleep(30 * 1000); } 這里先假定我們無法從代碼中看出ANR,為了分析ANR的原因,可以到處traces文件,如下所示,其中.表示當前目錄: adb pull /data/anr/traces.txt . traces文件一般是非常長的,下面是traces文件的部分內容: ----- pid 29395 at 2015-05-31 16:14:36----- Cmd line: com.ryg.chapter_15 DALVIK THREADS: (mutexes: tll=0 tsl=0 tscl=0 ghl=0) "main" prio=5 tid=1 TIMED_WAIT | group="main" sCount=1 dsCount=0 obj=0x4185b700 self=0x4012d0b0 | sysTid=29395 nice=0 sched=0/0 cgrp=apps handle=1073954608 | schedstat=( 0 0 0 ) utm=3 stm=2 core=2 at java.lang.VMThread.sleep(Native Method) at java.lang.Thread.sleep(Thread.java:1031) at java.lang.Thread.sleep(Thread.java:1013) at android.os.SystemClock.sleep(SystemClock.java:114) at com.ryg.chapter_15.MainActivity.onCreate(MainActivity.java:42) at android.app.Activity.performCreate(Activity.java:5086) at android.app.Instrumentation.callActivityOnCreate(Instrumentation. java:1079) at android.app.ActivityThread.performLaunchActivity(ActivityThread. java:2056) at android.app.ActivityThread.handleLaunchActivity(ActivityThread. java:2117) at android.app.ActivityThread.access$600(ActivityThread.java:140) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1213) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4914) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:808) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:575) at dalvik.system.NativeStart.main(Native Method) "Binder_2" prio=5 tid=10 NATIVE | group="main" sCount=1 dsCount=0 obj=0x42296d80 self=0x69068848 | sysTid=29407 nice=0 sched=0/0 cgrp=apps handle=1750664088 | schedstat=( 0 0 0 ) utm=0 stm=0 core=1 #00 pc 0000cc50 /system/lib/libc.so (__ioctl+8) #01 pc 0002816d /system/lib/libc.so (ioctl+16) #02 pc 00016f9d /system/lib/libbinder.so (android::IPCThreadState:: talkWithDriver(bool)+124) #03 pc 0001768f /system/lib/libbinder.so (android::IPCThreadState:: joinThreadPool(bool)+154) #04 pc 0001b4e9 /system/lib/libbinder.so #05 pc 00010f7f /system/lib/libutils.so (android::Thread::_threadLoop (void*)+114) #06 pc 00048ba5 /system/lib/libandroid_runtime.so (android::Android- Runtime::javaThreadShell(void*)+44) #07 pc 00010ae5 /system/lib/libutils.so #08 pc 00012ff0 /system/lib/libc.so (__thread_entry+48) #09 pc 00012748 /system/lib/libc.so (pthread_create+172) at dalvik.system.NativeStart.run(Native Method) 從traces的內容可以看出,主線程直接sleep了,而原因就是MainActivity的42行。第42行剛好就是SystemClock.sleep(30 * 1000),這樣一來就可以定位問題了。當然這個例子太直接了,下面再模擬一個稍微復雜點的ANR的例子。 下面的代碼也會導致ANR,原因是這樣的,在Activity的onCreate中開啟了一個線程,在線程中執行testANR(),而testANR()和initView()都被加了同一個鎖,為了百分之百讓testANR()先獲得鎖,特意在執行initView()之前讓主線程休眠了10ms,這樣一來initView()肯定會因為等待testANR()所持有的鎖而被同步住,這樣就產生了一個稍微復雜些的ANR。這個ANR是很參考意義的,這樣的代碼很容易在實際開發中出現,尤其是當調用關系比較復雜時,這個時候分析ANR日志就顯得異常重要了。下面的代碼中雖然已經將耗時操作放在線程中了,按道理就不會出現ANR了,但是仍然要注意子線程和主線程搶占同步鎖的情況。 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new Thread(new Runnable() { @Override public void run() { testANR(); } }).start(); SystemClock.sleep(10); initView(); } private synchronized void testANR() { SystemClock.sleep(30 * 1000); } private synchronized void initView() { } 為了分析問題,需要從traces文件著手,如下所示。 ----- pid 32662 at 2015-05-31 16:40:21----- Cmd line: com.ryg.chapter_15 DALVIK THREADS: (mutexes: tll=0 tsl=0 tscl=0 ghl=0) "main" prio=5 tid=1 MONITOR | group="main" sCount=1 dsCount=0 obj=0x4185b700 self=0x4012d0b0 | sysTid=32662 nice=0 sched=0/0 cgrp=apps handle=1073954608 | schedstat=( 0 0 0 ) utm=0 stm=4 core=0 at com.ryg.chapter_15.MainActivity.initView(MainActivity.java:~62) - waiting to lock <0x422a0120> (a com.ryg.chapter_15.MainActivity) held by tid=11 (Thread-13248) at com.ryg.chapter_15.MainActivity.onCreate(MainActivity.java:53) at android.app.Activity.performCreate(Activity.java:5086) at android.app.Instrumentation.callActivityOnCreate(Instrumentation. java:1079) at android.app.ActivityThread.performLaunchActivity(ActivityThread. java:2056) at android.app.ActivityThread.handleLaunchActivity(ActivityThread. java:2117) at android.app.ActivityThread.access$600(ActivityThread.java:140) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1213) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4914) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:808) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:575) at dalvik.system.NativeStart.main(Native Method) "Thread-13248" prio=5 tid=11 TIMED_WAIT | group="main" sCount=1 dsCount=0 obj=0x422b0ed8 self=0x683d20c0 | sysTid=32687 nice=0 sched=0/0 cgrp=apps handle=1751804288 | schedstat=( 0 0 0 ) utm=0 stm=0 core=0 at java.lang.VMThread.sleep(Native Method) at java.lang.Thread.sleep(Thread.java:1031) at java.lang.Thread.sleep(Thread.java:1013) at android.os.SystemClock.sleep(SystemClock.java:114) at com.ryg.chapter_15.MainActivity.testANR(MainActivity.java:57) at com.ryg.chapter_15.MainActivity.access$0(MainActivity.java:56) at com.ryg.chapter_15.MainActivity$1.run(MainActivity.java:49) at java.lang.Thread.run(Thread.java:856) 上面的情況稍微復雜一些,需要逐步分析。首先看主線程,如下所示。可以看得出主線程在initView方法中正在等待一個鎖<0x422a0120>,這個鎖的類型是一個MainActivity對象,并且這個鎖已經被線程id為11(即tid=11)的線程持有了,因此需要再看一下線程11的情況。 at com.ryg.chapter_15.MainActivity.initView(MainActivity.java:~62) - waiting to lock <0x422a0120> (a com.ryg.chapter_15.MainActivity) held by tid=11 (Thread-13248) tid是11的線程就是“Thread-13248”,就是它持有了主線程所需的鎖,可以看出“Thread-13248”正在sleep, sleep的原因是MainActivity的57行,即testANR方法。這個時候可以發現testANR方法和主線程的initView方法都加了synchronized關鍵字,表明它們在競爭同一個鎖,即當前Activity的對象鎖,這樣一來ANR的原因就明確了,接著就可以修改代碼了。 上面分析了兩個ANR的實例,尤其是第二個ANR在實際開發中很容易出現,我們首先要有意識地避免出現ANR,其次出現ANR了也不要著急,通過分析traces文件即可定位問題。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看