线程更新UI

来源:互联网 发布:淘宝内部券怎么找 编辑:程序博客网 时间:2024/05/16 10:22

简述

当第一次启动一个Android程序时,Android会自动创建一个称为“main”主线程的线程。这个主线程(也称为UI线程)很重要,因为它 负责把事件分派到相应的控件,其中就包括屏幕绘图事件,它同样是用户与Andriod控件交互的线程。比如,当你在屏幕上按下一个按钮后,UI线程会把这 个事件分发给刚按得那个按钮,紧接着按钮设置它自身为被按下状态并向事件队列发送一个无效(invalidate)请求。UI线程会把这个请求移出事件队 列并通知按钮在屏幕上重新绘制自身。

单线程模型会在没有考虑到它的影响的情况下引起Android应用程序性能低下,因为所有的任务都在同一个线程中执行,如果执行一些耗时的操作,如 访问网络或查询数据库,会阻塞整个用户界面。当在执行一些耗时的操作的时候,不能及时地分发事件,包括用户界面重绘事件。从用户的角度来看,应用程序看上 去像挂掉了。更糟糕的是,如果阻塞应用程序的时间过长(现在大概是5秒钟)Android会向用户提示一些信息,即打开一个“应用程序没有相应 (application not responding)”的对话框。

如果你想知道这有多糟糕,写一个简单的含有一个按钮的程序,并为按钮注册一个单击事件,并在事件处理器中调用这样的代码 Thread.sleep(2000)。在按下这个按钮这后恢复按钮的正常状态之前,它会保持按下状态大概2秒钟。如果这样的情况在你编写的应用程序中发 生,用户的第一反应就是你的程序运行很慢。

现在你知道你应该避免在UI线程中执行耗时的操作,你很有可能会在后台线程或工作者线程中执行这些耗时的任务,这样做是否正确呢?让我们来看一个例子,在这个例子中按钮的单击事件从网络上下载一副图片并使用ImageView来展现这幅图片。代码如下:

Java代码

public void onClick(View v){

new Thread( new Runnable(){

public void run(){

Bitmap b = loadImageFromNetwork();

mImageView.setImageBitmap(b);

}

}).start();

}

public void onClick(View v){    new Thread( new Runnable(){        public void run(){            Bitmap b = loadImageFromNetwork();            mImageView.setImageBitmap(b);        }    }).start();}

这段代码好像很好地解决了你遇到的问题,因为它不会阻塞UI线程。很不幸,它违背了单线程模型:Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。

使用Handler来更新UI

建立一个线程,设一个boolean变量来控制线程的运行,当收到被调用interrupt()时就产生InterruptedException异常,catch异常后改变变量,这样就可以停止线程了。

Java代码

private Thread thread = new Thread() {

@Override

public void run() {

boolean running = true;

while (running) {

try {

settime.sendMessage(settime.obtainMessage());

Thread.sleep(1000);

} catch (InterruptedException e) {

Log.d("Thread", "Exception");

running =false;

}

}

}

};

private Thread thread = new Thread() {       @Override       public void run() {              boolean running = true;              while (running) {                     try {                            settime.sendMessage(settime.obtainMessage());                            Thread.sleep(1000);                     } catch (InterruptedException e) {                            Log.d("Thread", "Exception");                            running =false;                     }              }       }};

Handler可以认为是消息队列,线程发送消息,主线程中的Handler收到消息,更新UI,这样就避免了UI在线程中被更新。

Java代码

private Handler settime = new Handler() {

Time t = new Time();

String time = new String();

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

t.setToNow();

tv_time.setText(time.format("%2d:%2d %d", t.hour, t.minute, t.second));

}

};

private Handler settime = new Handler() {       Time t = new Time();       String time = new String();       @Override       public void handleMessage(Message msg) {              super.handleMessage(msg);              t.setToNow();              tv_time.setText(time.format("%2d:%2d %d", t.hour, t.minute, t.second));       }};

调用interrupt()以停止线程运行

Java代码

b_cancel.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

thread.interrupt();

}

});

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 彪马运动裤买大了怎么办 淘宝卖家认证无法通过怎么办 淘宝开店申请未认证该怎么办 传照片到淘宝看不到照片怎么办 淘宝店铺秒出复核怎么办 钱盾身份认证一直不通过怎么办 淘宝开店一直不让认证通过怎么办 淘宝店铺不卖东西怎么办 企业误进虚空的增值税发票怎么办 唯品会商品有的不支持退换货怎么办 苹果手机和平板电脑共享怎么办 ipad被锁定了停用了怎么办 word文档被锁定不能编辑怎么办 苹果平板id忘了怎么办 ipad有id锁怎么办换主板 ipad刷机后忘记id密码怎么办 网购买东西手机号错了怎么办? 淘宝卖家虚假交易违规怎么办 好朋友问我借身份证开网店怎么办 为什么淘宝点开就跳过打不开怎么办 刹车油进眼睛里怎么办 眼睛被uv灯刺伤怎么办 眼睛被uv灯伤了怎么办 洗手台靠不到墙怎么办 加盟天猫优品不想干了怎么办 口袋侦探点开始就闪退怎么办 淘宝号被监控了怎么办 excel表格中把字体变细怎么办 wps方框中打字打不上怎么办 蘑菇街里面买东西受骗了怎么办? 淘宝买家号账户体检中心违规怎么办 支付宝充错手机账号怎么办 美团恶意差评怎么办 买家好评后追加差评怎么办 宝贝吃了一个金币怎么办 店铺微淘等级l1怎么办 淘宝占内存2个g怎么办 淘宝太占空间了怎么办 支付宝占内存大怎么办 苹果手机储存空间不足怎么办 小米平板电脑储存空间不足怎么办