导航:首页 > 操作系统 > androidanrservice

androidanrservice

发布时间:2022-05-23 22:27:59

‘壹’ android activity 中的 service 方法是否异步执行拜托各位大神

异步执行
android中,activity、service都是在主线程,service与activity的主要区别就是service没有前台界面,不能直接与用户交互,另外可以相对保证不会被系统随便的kill掉。所以service适用于一些无需交互的后台操作,但如果你直接在service中进行耗时操作的话,因为在主线程所以依然会出现和activity主线程一样的超时的问题,所以好的方式是在service中启动其他的线程去执行耗时操作。

‘贰’ 请教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。

‘叁’ 请教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)

‘肆’ android开发中为什么会出现anr

原因有3:
1.用户在进行了一种操作后5秒钟没有响应。
2.broadCastReceiver所进行的操作在10秒内没有完成。
3.Service在20秒内没返回结果。

‘伍’ 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。这种实践需要应用到所有显示用户界面的线程,因为他们都面临着同样的超时问题。

‘陆’ 安卓开发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();
}
}

‘柒’ 如何分析解决Android ANR

一:什么是ANR

ANR:Application Not Responding,即应用无响应二:ANR的类型

ANR一般有三种类型:

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

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

2:BroadcastTimeout(10 seconds)

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

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

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

Akey or touch event was not dispatched within the specified time(按键或触摸事件在特定时间内无响应)

具体的超时时间的定义在framework下的

ActivityManagerService.java

//How long we wait until we timeout on key dispatching.

staticfinal int KEY_DISPATCHING_TIMEOUT = 5*1000四:为什么会超时呢?

超时时间的计数一般是从按键分发给app开始。超时的原因一般有两种:

(1)当前的事件没有机会得到处理(即UI线程正在处理前一个事件,没有及时的完成或者looper被某种原因阻塞住了)

(2)当前的事件正在处理,但没有及时完成五:如何避免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
从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)

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

‘捌’ android如何连接SQLServer数据库我的出错!怎么解决

看你的code 在ui线程做数据库操作,很容易造成anr,可以用handler将数据库操作放在后台操作,显示的时候在ui线程。数据库连接的操作 搜索下一大堆

‘玖’ android anr多长时间

  1. broadcast超时时间为10秒

  2. 按键无响应的超时时间为5秒

  3. service ANR超时的定义在ActiveServices.java中

    前台service无响应的超时时间为20秒,后台service为200秒

阅读全文

与androidanrservice相关的资料

热点内容
app保存草稿怎么用 浏览:806
安卓如何进入proumb 浏览:141
主机虚拟云服务器 浏览:617
删除分区加密的空间会不会恢复 浏览:703
京东app客户上门怎么看搜索量 浏览:739
怎么在农行app购买黄金 浏览:45
c型开发板和单片机 浏览:146
虚拟机建立用户的模板文件夹 浏览:904
无锡代码编程培训班 浏览:631
eps图形数据加密 浏览:933
没有滴滴app怎么打车 浏览:101
大数乘法java 浏览:1001
如何登录服务器看源码 浏览:526
如何做服务器端 浏览:157
注册服务器地址指什么 浏览:435
文本命令行 浏览:98
扑克牌睡眠解压 浏览:197
rc4算法流程图 浏览:163
胡萝卜解压方法 浏览:40
扫描pdf格式软件 浏览:880