android4.0以上访问网络不能在主线程中进行以及在线程中操作UI的解决方法
MONO 调用一个线程操作UI 然后报Only the original thread that created a view hierarchy can touch its views。错误 google了一下说UI的操作还是需要到主线程,看了些java的例子 java中是使用了Handler 但是在MONO中需要怎么实现?
一.
RunOnUiThread(()=>执行语句 );
demo:
this.RunOnUiThread(() => tv.Text = "records: " + twt.Count.ToString());
二.
Handler实现也是可以的,关键代码
private Handler handler = new Handler();
Java.Lang.Runnable rb;
protected override void OnCreate(Bundle bundle){
rb = new Java.Lang.Runnable(() => {
button.Text = string.Format("{0} Runnable!", count++);
handler.PostDelayed(rb, 1000);
});
handler.PostDelayed(rb, 1000);}
三.其他方式
刚刚上手android,在写一个利用Socket与服务器端进行通信的Demo时候报了一个android.os.NetworkOnMainThreadException的异常:
服务器端:
public class SimpleServer {
public static void main(String[] args){
try {
ServerSocket ss=new ServerSocket(40000);
System.out.println("等待连接......");
while(true){
Socket s=ss.accept();
OutputStream os=s.getOutputStream();
os.write("hello".getBytes("utf-8"));
os.close();
s.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
求助度娘后发现是SDK的版本问题,android4.0中访问网络不能在主程序中进行,行吧,那就老老实实的重新开启一个线程:
new Thread(){
public void run(){
try {
Socket s=new Socket("172.22.16.26", 40000);
BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
String line=br.readLine();
show.setText("服务器说:"+line);
br.close();
s.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
结果又报了异常:
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
相信各位已经看出了在下犯了一个很低级的错误:在新启的线程中操作UI,UI线程是非线程安全的,Android平台不允许Activity新启动的线程访问该Activity里的界面组件,这时就要借助Handler的消息传递机制了:
new Thread(){
public void run(){
try {
Socket s=new Socket("172.18.6.26",40000);
BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
String line=br.readLine();
//System.out.println("服务器说:"+line);
Message msg=new Message();
msg.what=0x123;
msg.obj=line;
myhandler.sendMessage(msg);
br.close();
s.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
然后重写handlerMessage方法获取消息:
final Handler myhandler=new Handler(){
public void handleMessage(Message msg){
if(msg.what==0x123){
System.out.println("--------------->"+msg.obj);
show2.setText((String)msg.obj);
}
}
};
当新线程发送消息时,该方法自动被调用,handlerMessage(Message msg)方法依旧位于主线程中,所以可以动态的修改UI组件。
网络连接不能放在主线程
android 4.0 以上 网络连接不能放在主线程
4.0 以下 好像可以


在Android4.0以后,会发现,只要是写在主线程(就是Activity)中的HTTP请求,运行时都会报错,这是因为Android在4.0以后为了防止应用的ANR(aplication Not Response)异常,即使这里表达不是很清晰,大家应该都明白吧,哈哈
就针对此问题有两种解决的方法:
1.可以再Activity的onCreate()方法中加入这样一段代码,如下:
JAVA
if (Build.VERSION.SDK_INT >= 11) {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads ().detectDiskWrites().detectNetwork().penaltyLog().build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectLeakedClosableObjects().penaltyLog().penaltyDeath().build());
}
Mono 版
if (Build.VERSION.SdkInt.GetHashCode()>=11)
{
StrictMode.SetThreadPolicy(new StrictMode.ThreadPolicy.Builder().DetectDiskReads().DetectDiskWrites().DetectNetwork().PenaltyLog().Build());
StrictMode.SetVmPolicy(new StrictMode.VmPolicy.Builder().DetectLeakedSqlLiteObjects().DetectLeakedClosableObjects().PenaltyLog().PenaltyDeath().Build());
}
后就可以在主线程中进行网络操作了
2.一般情况我们应该这样做
启动一条子线程进行你的网络请求。
当然,如果你的应用程序执行的网络请求数据量很小的话,可以使用第一种方案
android4.0以上访问网络不能在主线程中进行以及在线程中操作UI的解决方法的更多相关文章
- 03_主线程联网问题&ANR&子线程不能修改UI
如果不使用HAXM,恐怕网页源码查看器无法获取servlet的源码.初步猜测是安卓模拟器运行速度太慢了.如果CPU不支持VT-x的话,HAXM是安装不上的.所以可以先开启VT-x. 可以参考几篇文章h ...
- android.os.NetworkOnMainThreadException 在4.0之后谷歌强制要求连接网络不能在主线程进行访问
谷歌在4.0系统以后就禁止在主线程中进行网络访问了,原因是: 主线程是负责UI的响应,如果在主线程进行网络访问,超过5秒的话就会引发强制关闭, 所以这种耗时的操作不能放在主线程里.放在子线程里,而子线 ...
- 有主线程发送message给子线程
通常我们在处理耗时任务时候都会通过新建线程来处理,当任务处理完后通过Handler将结果发送回主线程.比如下面示例: package com.example.testlistener; import ...
- 关于Quartus II 13.0对应开发NIOS II软件程序时报错Symbol 'NULL' could not be resolved问题的解决方法
关于Quartus II 13.0对应开发NIOS II软件程序时报错Symbol 'NULL' could not be resolved问题的解决方法 近期在评估使用NIOS II处理器进行项目的 ...
- 新安装 wampserver 出现 You don't have permission to access / on this server. 或者访问数据库出现You don't have permission to access /phpmyadmin/ on this server.(解决方法)转
本地搭建wamp,输入http://127.0.0.1访问正常,当输入http://localhost/,apache出现You don't have permission to access/on ...
- Ubuntu访问window下的磁盘分区出现“Error mounting /dev/sda5 at/media”错误的解决方法
我装ubuntu之前,电脑上安装了windows 10,为了装ubuntu,在window 10下的磁盘工具分配了30G的磁盘空间.安装完Ubuntu之后,访问window 10的磁盘分区出现“Err ...
- mono 3.4.0 make install的时候出现"找不到 Microsoft.Portable.Common.targets 文件”的错误提示解决方法
如果在这时就进行配置安装Mono的话,会在make阶段得到一个“找不到 Microsoft.Portable.Common.targets 文件”的错误提示, 所以需要先进行如下处理: #> c ...
- 安卓开发解决android.os.NetworkOnMainThreadException异常方法(主线程不能直接调用webservice)
安卓开发解决android.os.NetworkOnMainThreadException异常方法 2013-01-07 14:01:04| 分类: 技术 | 标签:安卓 技术 java | ...
- [置顶] 使用严苛模式打破Android4.0以上平台应用中UI主线程的“独断专行”
传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229 已经有好一段时间没有关注Android应用方面的事情了:)最近单位来了一个Androi ...
随机推荐
- gcc中支持的一种字符串表示方式
gcc支持的一种的字符串的表示形式 "xxx" "xxx" "xxx" 他会将这3个字符串连成一个并 且只会在最后的一个字符串末尾添加 '\ ...
- C++友元函数、友元类
1.什么是友元函数? 友元函数就是可以直接访问类的成员(包括私有数据)的非成员函数,也就是说他并不属于这个类,他是一种外部的函数. 一个外部函数只能通过类的授权成为这个类友元函数,这就涉及到一个关键字 ...
- .bat文件打开指定网页,并运行jar包
@echo off Start "" "C:\Users\Lenovo\AppData\Local\Google\Chrome\Application\chrome.ex ...
- 如何快速获取官网帮助信息 (附 11g pdf 文档)
http://docs.oracle.com/en/ 11g Release 2 (11.2) 搜索时指定网站 site:docs.oracle.com create table site:docs. ...
- 在Ubuntu14.04上安装WordPress4搭建技术博客
1.安装LAMP环境 1.1 安装Apache2 1.2 安装MySQL5 1.3 安装PHP5 1.4 安装phpMyAdmin 2.初始化数据库 3.下载并配置WordPress 4.配置Apac ...
- java向数据库插入N条数据
为了测试mysql的索引,要向数据库先插入上万条数据,然后再测试.手动插入太麻烦,写了一段代码. 先上代码: package action; import java.sql.Connection; i ...
- [Git00] Pro Git 一二章读书笔记
记得知乎以前有个问题说:如果用一天的时间学习一门技能,选什么好?里面有个说学会Git是个很不错选择,今天就抽时间感受下Git的魅力吧. Pro Git (Scott Chacon) 读书笔记: ...
- Jenkins Pipeline+sonar构建质量平台
前提: Jenkins JDK 目录: 1.安装sonar插件:SonarQube Scanner for Jenkins 2.安装SonarQube 3.安装sonar-scanner ++++++ ...
- angular响应式表单 - 状态字段
用于表单验证的过程: touched,untoched pristine,dirty pending
- DotNetBar.MetroTilePanel 样式、加载数据、获取数据
描述下:MetroTilePanel包含子集ItemContainer 子集下面又包含子集MetroTileItem 目前我用到的就是这三层 因为需求所以整个模块全部由代码实现 1.ItemCon ...