導航:首頁 > 操作系統 > androidserviceanr

androidserviceanr

發布時間:2023-03-13 16:46:17

A. android anr多長時間

  1. broadcast超時時間為10秒

  2. 按鍵無響應的超時時間為5秒

  3. service ANR超時的定義在ActiveServices.java

    前台service無響應的超時時間為20秒,後台service為200秒

B. Android如何避免ANR

ANR:Application Not Responding,五秒在Android中,活動管理器和窗口管理器這兩個系統服務負責監視應用程序的響應。當出現下列情況時,Android就會顯示ANR對話框了: 對輸入事件(如按鍵、觸摸屏事件)的響應超過5秒 意向接受器(intentReceiver)超過10秒鍾仍未執行完畢
Android應用程序完全運行在一個獨立的線程中(例如main)。這就意味著,任何在主線程中運行的,需要消耗大量時間的操作都會引發ANR。因為此時,你的應用程序已經沒有機會去響應輸入事件和意向廣播(Intent broadcast)。 因此,任何運行在主線程中的方法,都要盡可能的只做少量的工作。特別是活動生命周期中的重要方法如onCreate()和 onResume()等更應如此。潛在的比較耗時的操作,如訪問網路和資料庫;或者是開銷很大的計算,比如改變點陣圖的大小,需要在一個單獨的子線程中完成(或者是使用非同步請求,如資料庫操作)。但這並不意味著你的主線程需要進入阻塞狀態已等待子線程結束 -- 也不需要調用Therad.wait()或者Thread.sleep()方法。取而代之的是,主線程為子線程提供一個句柄(Handler),讓子線程在即將結束的時候調用它(xing:可以參看Snake的例子,這種方法與以前我們所接觸的有所不同)。使用這種方法涉及你的應用程序,能夠保證你的程序對輸入保持良好的響應,從而避免因為輸入事件超過5秒鍾不被處理而產生的ANR。這種實踐需要應用到所有顯示用戶界面的線程,因為他們都面臨著同樣的超時問題。

C. 請教android service ANR問題

剛拿到anr的trace,還是無頭緒,都是調用棧的mp,仔細看看,發現一個很好的信息隱藏在這個棧幀信息中:
如下一個棧幀:
----- pid 861 at 2012-02-11 14:57:50 -----
Cmd line: system_server
DALVIK THREADS:
(mutexes: tll=0 tsl=0 tscl=0 ghl=0)
"main" prio=5 tid=1 MONITOR
| group="main" sCount=1 dsCount=0 obj=0x2ba9c460 self=0x8e820
| sysTid=861 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=716342112
| schedstat=( 0 0 0 ) utm=464 stm=65 core=0
at com.android.server.am.ActivityManagerService.isUserAMonkey(ActivityManagerService.java:~6546)
- waiting to lock <0x2c1141c8> (a com.android.server.am.ActivityManagerService) held by tid=59 (Binder Thread #6)
at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:1273)
at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:1545)
at android.os.Binder.execTransact(Binder.java:338)
at com.android.server.SystemServer.init1(Native Method)
at com.android.server.SystemServer.main(SystemServer.java:808)
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:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)

這說明什麼?看上面的紅色部分,說明這個主線程在等待鎖一個object 0x2c1141c8 (通常就是synchronized操作,這里就是com.android.server.am.ActivityManagerService類型的一個object),但被tid=59佔住了, 再看看 tid=59的棧幀:
"Binder Thread #6" prio=5 tid=59 MONITOR
| group="main" sCount=1 dsCount=0 obj=0x2c3bd838 self=0x34c5d8
| sysTid=1120 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=3460688
| schedstat=( 0 0 0 ) utm=168 stm=48 core=0
at com.android.server.am.BatteryStatsService.noteStopWakelock(BatteryStatsService.java:~114)
- waiting to lock <0x2c117d50> (a com.android.internal.os.BatteryStatsImpl) held by tid=13 (ProcessStats)
at com.android.server.PowerManagerService.noteStopWakeLocked(PowerManagerService.java:798)
at com.android.server.PowerManagerService.releaseWakeLockLocked(PowerManagerService.java:1015)
at com.android.server.PowerManagerService.releaseWakeLock(PowerManagerService.java:967)
at android.os.PowerManager$WakeLock.release(PowerManager.java:319)
at android.os.PowerManager$WakeLock.release(PowerManager.java:300)
at com.android.server.am.ActivityStack.activityIdleInternal(ActivityStack.java:3254)
at com.android.server.am.ActivityManagerService.activityIdle(ActivityManagerService.java:3953)
at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:362)
at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:1545)
at android.os.Binder.execTransact(Binder.java:338)
at dalvik.system.NativeStart.run(Native Method)

tid為何沒有釋放鎖object 0x2c1141c8呢?因為它在等到鎖 object 0x2c117d50(一個com.android.internal.os.BatteryStatsImpl類型的對象)!如果大家有較豐富的捉蟲經驗的話,看到這, 想必都清楚了,持鎖時又請求鎖,極大的可能就是死鎖了!

再看請求的鎖被tid=13持有的情況吧:
"ProcessStats" prio=5 tid=13 MONITOR
| group="main" sCount=1 dsCount=0 obj=0x2c146f58 self=0x2954f0
| sysTid=877 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=2709096
| schedstat=( 0 0 0 ) utm=6 stm=4 core=0
at com.android.server.am.ActivityManagerService.broadcastIntent(ActivityManagerService.java:~12430)
- waiting to lock <0x2c1141c8> (a com.android.server.am.ActivityManagerService) held by tid=59 (Binder Thread #6)
at android.app.ContextImpl.sendBroadcast(ContextImpl.java:909)
at com.android.server.DropBoxManagerService.add(DropBoxManagerService.java:236)
at android.os.DropBoxManager.addText(DropBoxManager.java:272)
at com.android.server.am.ActivityManagerService$11.run(ActivityManagerService.java:7630)
at com.android.server.am.ActivityManagerService.addErrorToDropBox(ActivityManagerService.java:7635)
at com.android.server.am.ActivityManagerService.handleApplicationWtf(ActivityManagerService.java:7448)
at com.android.internal.os.RuntimeInit.wtf(RuntimeInit.java:345)
at android.util.Log$1.onTerribleFailure(Log.java:103)
at android.util.Log.wtf(Log.java:278)
at com.android.internal.os.BatteryStatsImpl.(BatteryStatsImpl.java:5738)
at com.android.internal.os.BatteryStatsImpl.access$100(BatteryStatsImpl.java:76)
at com.android.internal.os.BatteryStatsImpl$Uid.(BatteryStatsImpl.java:2457)
at com.android.internal.os.BatteryStatsImpl$Uid.getTcpBytesReceived(BatteryStatsImpl.java:2446)
at com.android.internal.os.BatteryStatsImpl.writeSummaryToParcel(BatteryStatsImpl.java:5437)
at com.android.internal.os.BatteryStatsImpl.writeLocked(BatteryStatsImpl.java:4836)
at com.android.internal.os.BatteryStatsImpl.writeAsyncLocked(BatteryStatsImpl.java:4818)
at com.android.server.am.ActivityManagerService.updateCpuStatsNow(ActivityManagerService.java:1649)
at com.android.server.am.ActivityManagerService$3.run(ActivityManagerService.java:1531)

D. Android ANR 機制

廣播的 ANR 處理相對簡單,主要是再次判斷是否超時、記錄日誌,記錄 ANR 次數等。然後就繼續調用 processNextBroadcast 函數,處理下一條廣播了。

ContentProvider 超時為 CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10s

Activity 的 ANR 是相對最復雜的,也只有 Activity 中出現的 ANR 會彈出 ANR 提示框。
最終的表現形式是:彈出一個對話框,告訴用戶當前某個程序無響應,輸入一大堆與 ANR 相關的日誌,便於開發者解決問題。

InputDispatching:

Activity 最主要的功能之一是交互,為了方便交互,Android 中的 InputDispatcher 會發出操作事件,最終在 InputManagerService 中發出事件,通過 InputChannel,向 Activity 分發事件。交互事件必須得到響應,如果不能及時處理,IMS 就會報出 ANR,交給 AMS 去彈出 ANR 提示框。

KeyDispatching:

如果輸入是個 Key 事件,會從 IMS 進入 ActivityRecord.Token.keyDispatchingTimeOut,然後進入 AMS 處理,不同的是,在 ActivityRecord 中,會先截留一次 Key 的不響應,只有當 Key 連續第二次處理超時,才會彈出 ANR 提示框。

窗口焦點:

Activity 總是需要有一個當前窗口來響應事件的,但如果遲遲沒有當前窗口(獲得焦點),比如在 Activity 切換時,舊 Activity 已經 onPause,新的 Activity 一直沒有 onResume,持續超過 5 秒,就會 ANR。
App 的生命周期太慢,或 CPU 資源不足,或 WMS 異常,都可能導致窗口焦點。

1. 判斷是否有 focused 組件以及 focused Application:

這種一般是在應用啟動時觸發,比如啟動時間過長在這過程中觸發了 keyevent 或者 trackball moteionevent 就會出現。

對應於

2. 判斷前面的事件是否及時完成:

對應於

出現這種問題意味著主線程正在執行其他的事件但是比較耗時導致輸入事件無法及時處理。

InputDispatcher 超時是最常見的 ANR 類型,而且其類型也比較多。
當用戶觸摸屏幕或者按鍵操作,首次觸發的是硬體驅動,驅動收到事件後,將該相應事件寫入到輸入設備節點, 這便產生了最原生態的內核事件。接著,輸入系統取出原生態的事件,經過層層封裝後成為 KeyEvent 或者 MotionEvent ;最後,交付給相應的目標窗口(Window)來消費該輸入事件。可見,輸入系統在整個過程起到承上啟下的銜接作用。

Input 模塊的主要組成:

每一個應用進程都會有一個 SignalCatcher 線程,專門處理 SIGQUIT,來到 art/runtime/signal_catcher.cc :

當應用發生 ANR 之後,系統會收集許多進程,來 mp 堆棧,從而生成 ANR Trace 文件。收集的第一個,也是一定會被收集到的進程,就是發生 ANR 的進程。接著系統開始向這些應用進程發送 SIGQUIT 信號,應用進程收到 SIGQUIT 後開始 mp 堆棧。

[1] developer ANRs
[2] Android ANR 分析詳解
[3] 看完這篇 Android ANR 分析,就可以和面試官裝逼了!
[4] 微信 Android 團隊手把手教你高效監控 ANR
[5] Input 系統—ANR 原理分析 - Gityuan
[6] 徹底理解安卓應用無響應機制 - Gityuan
[7] 理解 Android ANR 的觸發原理 - Gityuan

E. android activity 中的 service 方法是否非同步執行拜託各位大神

非同步執行
android中,activity、service都是在主線程,service與activity的主要區別就是service沒有前台界面,不能直接與用戶交互,另外可以相對保證不會被系統隨便的kill掉。所以service適用於一些無需交互的後台操作,但如果你直接在service中進行耗時操作的話,因為在主線程所以依然會出現和activity主線程一樣的超時的問題,所以好的方式是在service中啟動其他的線程去執行耗時操作。

F. 請教android service ANR問題

ANR(ApplicationNotResponding)ANR定義:在Android上,如果你的應用程序有一段時間響應不夠靈敏,系統會向用戶顯示一個對話框,這個對話框稱作應用程序無響應(ANR:ApplicationNotResponding)對話框。用戶可以選擇「等待」而讓程序繼續運行,也可以選擇「強制關閉」。所以一個流暢的合理的應用程序中不能出現anr,而讓用戶每次都要處理這個對話框。因此,在程序里對響應性能的設計很重要,這樣系統不會顯示ANR給用戶。默認情況下,在android中Activity的最長執行時間是5秒,BroadcastReceiver的最長執行時間則是10秒。第一:什麼會引發ANR?在Android里,應用程序的響應性是由ActivityManager和WindowManager系統服務監視的。當它監測到以下情況中的一個時,Android就會針對特定的應用程序顯示ANR:在5秒內沒有響應輸入的事件(例如,按鍵按下,屏幕觸摸)2.BroadcastReceiver在10秒內沒有執行完畢造成以上兩點的原因有很多,比如在主線程中做了非常耗時的操作,比如說是下載,io異常等。潛在的耗時操作,例如網路或資料庫操作,或者高耗時的計算如改變點陣圖尺寸,應該在子線程里(或者以資料庫操作為例,通過非同步請求的方式)來完成。然而,不是說你的主線程阻塞在那裡等待子線程的完成——也不是調用Thread.wait()或是Thread.sleep()。替代的方法是,主線程應該為子線程提供一個Handler,以便完成時能夠提交給主線程。以這種方式設計你的應用程序,將能保證你的主線程保持對輸入的響應性並能避免由於5秒輸入事件的超時引發的ANR對話框。第二:如何避免ANR?1、運行在主線程里的任何方法都盡可能少做事情。特別是,Activity應該在它的關鍵生命周期方法(如onCreate()和onResume())里盡可能少的去做創建操作。(可以採用重新開啟子線程的方式,然後使用Handler+Message的方式做一些操作,比如更新主線程中的ui等)2、應用程序應該避免在BroadcastReceiver里做耗時的操作或計算。但不再是在子線程里做這些任務(因為BroadcastReceiver的生命周期短),替代的是,如果響應Intent廣播需要執行一個耗時的動作的話,應用程序應該啟動一個Service。(此處需要注意的是可以在廣播接受者中啟動Service,但是卻不可以在Service中啟動broadcasereciver,關於原因後續會有介紹,此處不是本文重點)3、避免在IntentReceiver里啟動一個Activity,因為它會創建一個新的畫面,並從當前用戶正在運行的程序上搶奪焦點。如果你的應用程序在響應Intent廣播時需要向用戶展示什麼,你應該使用NotificationManager來實現。總結:anr異常也是在程序中自己經常遇到的問題,主要的解決法自己最常用的就是不要在主線程中做耗時的操作,而應放在子線程中來實現,比如採用Handler+mesage的方式,或者是有時候需要做一些和網路相互交互的耗時操作就採用asyntask非同步任務的方式(它的底層其實Handler+mesage有所區別的是它是線程池)等,在主線程中更新UI。

G. 如何分析解決Android ANR

Android ANR是程序無法響應的問題,可以由以下方式解決:

  1. 將一些消耗時間的代碼放到Handler類裡面去執行,相當於另外開一個線程,不會阻塞主線程,從而避免引發ANR的問題,如下代碼:


    private Handler handler = new Handler(); //新建一個handler類

    private Runnable myRunnable= new Runnable() { //新建一個Runnable來開設一個線程

    public void run() {

    if (run) {

    handler.postDelayed(this, 1000);

    count++;

    }

    tvCounter.setText("Count: " + count); //裡面來執行一些控制項的更新


    }

    };

  2. 應用程序應該避免在BroadcastReceiver里做耗時的操作或計算。但不再是在子線程里做這些任務(因為 BroadcastReceiver的生命周期短),替代的是,如果響應Intent廣播需要執行一個耗時的動作的話,應用程序應該啟動一個 Service。

H. 安卓開發ANR怎麼處理

原因分析:android系統中處理用戶操作的工作時在主線程中執行的,如果我們的程序在主線程中進行一些耗時的操作,導致用戶的操作6秒不能夠處理,就會出現異常。
主線程休眠,那麼再點擊程序,必須等主線程睡醒後才會反應。
所以在主線程中不要做太耗時的工作,因為主界面會阻塞。

解決辦法:讓這些耗時的操作放在新線程裡面操作。
注意:如果新線程裡面做的事情要更新界面的話,就要使用handler來操作。
連接網路的事都要放在新線程裡面的。
解決代碼(包括更新界面的操作,使用的是handler):

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
private TextView numTV;
private Handler handler = new Handler();
private int i;

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

numTV = (TextView) findViewById(R.id.numTV);
}

public void doSomething(View view) throws Exception {
new Thread() {
public void run() {
for (i = 1; i < 20; i++) {
handler.post(new Runnable() {
public void run() {
numTV.setText(i + "");
}
});
System.out.println(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}.start();
}

public void toast(View view) {
Toast.makeText(this, "十八大開幕了!", 0).show();
}
}

閱讀全文

與androidserviceanr相關的資料

熱點內容
伺服器如何配置host 瀏覽:1001
守望執行命令 瀏覽:371
加密狗插上去了怎麼辦 瀏覽:624
錘子m1怎麼把文件夾重置 瀏覽:213
APP的數據會存在哪裡 瀏覽:66
一支輕快又解壓的舞 瀏覽:588
80x86編程手冊 瀏覽:767
android機制使用 瀏覽:363
國外太空探索網站源碼 瀏覽:645
dotaimba命令大全 瀏覽:15
手解剖pdf 瀏覽:735
單片機無法燒寫程序 瀏覽:415
pline命令 瀏覽:113
760貼片機編程視頻 瀏覽:335
歐姆龍plc編程第36講 瀏覽:917
我的世界如何將一個伺服器弄崩 瀏覽:10
php網站訪問量代碼 瀏覽:433
怠速壓縮機咔咔響 瀏覽:178
怎麼才能修改APP中的數據 瀏覽:690
哪裡有搶單的app 瀏覽:464