我们在开发android程序的时候,无论你使用URLConnection还是HttpClient操作,经常遇到Timeout现象,这个时候如果你检查了网络是正常的,手动浏览器访问目标web地址也可以正常浏览的话,估摸着下面的情况对你有用
我遇到的情况就是,在一些2.X系统手机上访问URL正常,但是在4.x系统手机上就报错:
03-07 13:17:06.132: E/ConnectionManager(25522): android.os.NetworkOnMainThreadException
或者一些Timeout的异常
通过查阅相关资料,发现,自从Android 2.3之后,系统增加了一个类:StrictMode。这个类对网络的访问方式进行了一定的改变。
Android的官方文档给出了这个类设置的目的:
StrictMode是一个系统提供的开发工具,用以检测在开发过程中因为偶然的事故从而造成的系统潜在的问题,进而提示开发者对其进行修复。
StrictMode通常用于捕获磁盘访问或者网络访问中与主进程之间交互产生的问题,因为在主进程中,UI操作和一些动作的执行是最经常用到的,它们之间会产生一定的冲突问题。将磁盘访问和网络访问从主线程中剥离可以使磁盘或者网络的访问更加流畅,提升响应度和用户体验。
显然,大多数初学者在进行网络开发时,会选择将访问网络的代码直接放到主进程中,由于和主进程的首要工作——UI交互——相矛盾,因此,必须设置一定的检测机制,以保证系统运行的流畅,所有的异常都可以被检测。
Android文档建议我们增加这两条命令:
2
3
4
5
6
7
8
9
10
11
|
StrictMode.setThreadPolicy(
new
StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
// or .detectAll() for all detectable problems
.penaltyLog()
.build());
StrictMode.setVmPolicy(
new
StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
//探测SQLite数据库操作
.penaltyLog()
//打印logcat
.penaltyDeath()
.build());
|
即使这样子的话,在4.x系统手机上还是会报错,但是不会中断程序执行;
其实我的程序是一个webview做的android app壳, js通过webview跟native交互,让native做一些代理访问操作,html5部分会去做存储展示操作,也就说js做的一些存储操作和native做的网络访问有可能在并发执行,StrictMode只不过更好地检测出来而已。