Xamarin.Android 使用线程无法更改页面文本问题
前言:
刚接触Xamarin.Android不到一个月时间,却被他折磨的不要不要的,随着开发会出现莫名其妙的问题,网上类似Xamarin.Android的文档也不多,于是本片文章是按照Java开发Android的思路写过来的,于是记录下来,希望大家碰到这个问题少走些弯路。
问题描述:
在执行线程内想给TextView赋值发生错误。
错误提示:
Android.Util.AndroidRuntimeException: Only the original thread that created a view hierarchy can touch its views.
问题原因:
原来Android中相关的view和控件不是线程安全的,我们必须单独做处理。这里借此引出Handler的使用。
Handler的机制:
handler机制,在android中提供了一种异步回调机制Handler,使用它,我们可以在完成一个很长时间的任务后做出相应的通知。
Handler的作用:
当我们需要在子线程处理耗时的操作(例如访问网络,数据库的操作),而当耗时的操作完成后,需要更新UI,这就需要使用Handler来处理,因为子线程不能做更新UI的操作。Handler能帮我们很容易的把任务(在子线程处理)切换回它所在的线程。简单理解,Handler就是解决线程和线程之间的通信的。
原有错误代码:
- using System;
- using Android.App;
- using Android.Content;
- using Android.Runtime;
- using Android.Views;
- using Android.Widget;
- using Android.OS;
- using System.Threading;
- namespace App1
- {
- [Activity(Label = "App1", MainLauncher = true, Icon = "@drawable/icon")]
- public class MainActivity : Activity
- {
- TextView tv1;
- protected override void OnCreate(Bundle bundle)
- {
- base.OnCreate(bundle);
- SetContentView(Resource.Layout.Main);
- Button button = FindViewById<Button>(Resource.Id.MyButton);
- button.Click += delegate { TestThread(); };
- tv1 = FindViewById<TextView>(Resource.Id.textView1);
- }
- private void TestThread()
- {
- Boolean loopFlag = true;
- Thread th = new Thread(new ThreadStart(delegate
- {
- int i = ;
- while (loopFlag && i < )
- {
- if (i == )
- {
- tv1.Text = "测试赋值";
- loopFlag = false;
- }
- i++;
- }
- }));
- th.Start();
- }
- }
- }
修改完成后的代码:
- using System;
- using Android.App;
- using Android.Content;
- using Android.Runtime;
- using Android.Views;
- using Android.Widget;
- using Android.OS;
- using System.Threading;
- namespace App1
- {
- [Activity(Label = "App1", MainLauncher = true, Icon = "@drawable/icon")]
- public class MainActivity : Activity
- {
- TextView tv1;
- Handler hander;
- protected override void OnCreate(Bundle bundle)
- {
- base.OnCreate(bundle);
- SetContentView(Resource.Layout.Main);
- Button button = FindViewById<Button>(Resource.Id.MyButton);
- hander = new UIHand(this);
- button.Click += delegate { TestThread(); };
- tv1 = FindViewById<TextView>(Resource.Id.textView1);
- }
- //模拟一个线程,在线程中修改TextView的文本
- private void TestThread()
- {
- Boolean loopFlag = true;
- Thread th = new Thread(new ThreadStart(delegate
- {
- int i = ;
- while (loopFlag && i < )
- {
- if (i == )
- {
- Message ms = new Message();
- ms.Obj = "测试赋值" + "@" + "";
- hander.SendMessage(ms); //调用HandleMessage方法
- loopFlag = false;
- }
- i++;
- }
- }));
- th.Start();
- }
- //创建一个类,继承于Handler
- private class UIHand : Handler
- {
- MainActivity ma;
- public UIHand(MainActivity _ma)
- {
- ma = _ma;
- }
- //重写HandleMessage方法
- public override void HandleMessage(Message msg)
- {
- try
- {
- String result = msg.Obj + ""; //相当于ToString();
- String[] str = result.Split('@');
- ma.tv1.Text = str[];
- }
- catch (Exception)
- {
- }
- }
- }
- }
- }
这样问题就完美的解决了。
Xamarin.Android 使用线程无法更改页面文本问题的更多相关文章
- xamarin android 在代码中如何设置文本颜色
xamarin android 在代码中如何设置文本颜色 TextView v = FindViewById<TextView>(Android.Resource.Id.Message); ...
- Xamarin.Android 使用Timer 并更改UI
http://blog.csdn.net/ozhangsan12345/article/details/72653070 第一步:创建timer对象 //创建timer对象 Timer _dispat ...
- 更改Xamarin Android App名称
更改Xamarin Android App名称 Xamarin Android生成的App名称默认和项目名一致.修改该名称有两种方式. 第一种方式:右击Android项目,选择“属性”命令,然 ...
- Visual Studio跨平台开发实战(5) - Xamarin Android多页面应用程式开发
原文 Visual Studio跨平台开发实战(5) - Xamarin Android多页面应用程式开发 前言 大部份的Android 都具有实体或虚拟的Back键. 因此在处理多页面应用程式时 ...
- Xamarin Android自定义文本框
xamarin android 自定义文本框简单的用法 关键点在于,监听EditText的内容变化,不同于java中文本内容变化去调用EditText.addTextChangedListener(m ...
- Visual Studio跨平台开发(5):Xamarin Android多页面应用开发
前言 大部份的Android 都具有实体或虚拟的Back键. 因此在处理多页面应用程序时, 与先前所介绍的iOS Navigation controller 比较起来会简单许多. 1. 开启Visua ...
- Xamarin.Android开发
使用 Visual Studio 生成第一个 Xamarin.Android 应用程序,并进一步了解使用 Xamarin 进行 Android 应用程序开发的基础知识.在此过程中,会介绍生成和部署 X ...
- [译]:Xamarin.Android开发入门——Hello,Android深入理解
返回索引目录 原文链接:Hello, Android_DeepDive. 译文链接:Xamarin.Android开发入门--Hello,Android深入理解 本部分介绍利用Xamarin开发And ...
- Xamarin.Android 如何使用Assets目录下的文件
原文:Xamarin.Android 如何使用Assets目录下的文件 个人原创,转载注明出处:http://blog.csdn.net/supluo/article/details/43672411 ...
随机推荐
- Python学习之MacBook Pro中PyCharm安装pip以及itchat
前言:Mac中自带的python没有用,自己安装了一个PyCharm,网上很多人说安装Itchat后会安装到自带的Python中去.本文记录怎么安装到自己安装的Python3.7中去.主要技术来源于h ...
- Python练习-生成器、迭代器-2018.12.01
如果列表元素可以按照某种算法推算出来,可以在循环的过程中不断推算出后续的元素.这样就不必创建完整的list,从而节省大量的空间.在Python中,这种一边循环一边计算的机制,称为生成器:generat ...
- [leetcode]49. Group Anagrams变位词归类
Given an array of strings, group anagrams together. Example: Input: ["eat", "tea" ...
- ES6 proxy(代理拦截) &&Reflect
- 现代编译原理--第六章(中间树 IR Tree 含源码)
(转载请表明出处 http://www.cnblogs.com/BlackWalnut/p/4559717.html ) 这一章,就虎书而言,理论知识点是及其少的,就介绍了为什么要有一个中间表示树 ...
- CentOS 系统 git clone出错
CentOS 操作系统 安装npm git clone 项目时出现类似如下错误: fatal: unable to access 'https://github.com/creationix/nvmg ...
- day3-selenium的使用及
如果是python2的情况下需要设置: # _*_ coding:utf-8 _*_,这样的编码来保证输入中文在运行时不会报错,另外在中文的前边加上u保证编译时不会报错 from selenium i ...
- list(zip(*querySet))使用
teacher_cls_list = obj.cls.all().values_list('id', 'caption') #list(zip(*list)),将数组中的元组中的每一项取出,添加到一起 ...
- Django获取数据库数据时根据id筛选
filter(id__in=models.Teacher.objects.all()[0:5]) teacher_list = models.Teacher.objects.filter(id__in ...
- Python:每日一题001
题目:有四个数字:1.2.3.4,能组成多少个互不相同且无重复数字的三位数?各是多少? **程序分析:可填在百位.十位.个位的数字都是1.2.3.4.组成所有的排列后再去 掉不满足条件的排列. 个人解 ...