Android:在一个非主线程内直接调用UI线程的Handler实例,这样没问题吗?

 我来答
huanglenzhi
2015-02-17 · 知道合伙人数码行家
huanglenzhi
知道合伙人数码行家
采纳数:117538 获赞数:517183
长期从事计算机组装,维护,网络组建及管理。对计算机硬件、操作系统安装、典型网络设备具有详细认知。

向TA提问 私信TA
展开全部
  我们开发应用程序的时候,处于线程安全的原因子线程通常是不能直接更新主线程(UI线程)中的UI元素的,那么在Android开发中有几种方法解决这个问题,其中方法之一就是利用Handler处理的。

  下面说下有关Handler相关的知识。
  多线程一些基础知识回顾:
  在介绍Handler类相关知识之前,我们先看看在Java中是如何创建多线程的
  方法有两种:
  通过继承Thread类,重写Run方法来实现
  通过继承接口Runnable实现多线程

  接下来让我们看看Handler是什么?如何来用

  Handler是这么定义的:
  主要接受子线程发送的数据, 并用此数据配合主线程更新UI.

  Handler的主要作用:主要用于异步消息的处理

  Handler的运行过程:
  当(子线程)发出一个消息之后,首先进入一个(主线程的)消息队列,发送消息的函数即刻返回,而在主线程中的Handler逐个的在消息队列中将消息取出,然后对消息进行处理。这样就实现了跨线程的UI更新(实际上还是在主线程中完成的)。
  这种机制通常用来处理相对耗时比较长的操作,如访问网络比较耗时的操作,读取文大文件,比较耗时的操作处理等。

  在大白话一点的介绍它的运行过程:
  启动应用时Android开启一个主线程 (也就是UI线程) , 如果此时需要一个耗时的操作,例如: 联网读取数据,或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,如果你放在主线程中的话,界面会出现假死现象(这也就是你在主线程中直接访问网络时会提示你异常的原因,如我们上篇文章所述Android主线程不能访问网络异常解决办法
  )。
  这个时候我们需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,Android主线程是线程不安全的,更新UI只能在主线程中更新.。
  这个时候,Handler就出现了,来解决这个复杂的问题,由于Handler运行在主线程中(UI线程中), 它与子线程可以通过Message对象来传递数据, 这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传弟)Message对象,(里面包含数据) , 把这些消息放入主线程队列中,配合主线程进行更新UI。

  接下来我们看看关于Handler都有哪些方法(它都能干什么):
  其中Handler对象的一些主要方法,如下:

  post(Runnable) postAtTime(Runnable,long)

  postDelayed(Runnable long)

  sendEmptyMessage(int)

  sendMessage(Message)

  sendMessageAtTime(Message,long)

  sendMessageDelayed(Message,long)

  正如方法名字中看到的,有两类方法:

  (1)在某个主线程中执行Runnable
  (2)在子线程中发送一个消息,在主线程中检测该消息处理

  线程间传递Message对象的sendMessage方法和发送Runnable多线程对象的post方法。正对应着上面所说的两个特性1)、2)

  下面开发个Handler实例做说明:
  用post的方法执行一个Runnable对象,在该对象中随机产生一个10-100之间的随机数,赋值到UI主线程中的TextView中线程,执行5次,每次相隔5秒, 拼接每次的数字, 最后执行结果应该如:10 22 33 44 61

  主要代码如下:
  int i = 0;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  handler.post(run);
  }

  Handler handler = new Handler(){
  @Override
  public void handleMessage(Message msg){
  String s = String.valueOf(msg.what);
  TextView tv = (TextView)findViewById(R.id.textView);
  tv.setText(tv.getText() + ” ” + s);
  }
  };

  Runnable run = new Runnable(){
  @Override
  public void run(){
  Random r = new Random();
  int rnum = r.nextInt((100 – 10) + 1) + 10;
  handler.sendEmptyMessage(rnum);
  handler.postDelayed(run, 5000);
  i++;
  if (i==5){
  handler.removeCallbacks(run);
  }
  }
  };
追问
你复制了这么多,意思是说可以在新线程中直接(注意,是‘直接’,不是传参,传递过来)使用UI线程中的handler变量?
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式