handler.post(r)其实这样并不会新起线程,只是执行的runnable里的run()方法,却没有执行start()方法,所以runnable走的还是UI线程。

1.如果像这样,是可以操作ui,但是run还是走在主线程,见打印出来的Log线程名字是main,说明是主线程。

这就是为什么可以直接在run方法里操作ui,因为它本质还是ui线程

handler.post(new Runnable(){
   public void run(){
   Log.e("当前线程:",Thread.currrentThread.getName());//这里打印de结果会是main
   setTitle("哈哈");
       }
 });

2.通过HandlerThread获取到looper却是可以新起线程,但是在这里的run方法里操作ui是不可能的,但是这显然有个缺点,如果你执行多次post(r)方法其实走的还是HandlerThread线程。假如你执行5次,n次,其实还是一次并且它们是串行的。假如下载5张图片,你会看到图片是下完第一张,才会去下第二张。

实践证明,只有是拥有主线程looper的handler才可以操作ui,而在主线程操作ui可以在handler的handlerMessage()方法中操作Ui,也可以在handler的post(r)的run方法里操作Ui.

HandlerThread ht = new HandlerThread("handler thread");
 ht.start();
 handler = new Handler(ht.getLooper());
 handler.post(new Runnable(){//这里run()方法其实还是在等ht.start()调用
   public void run(){
   Log.e("当前线程:",Thread.currrentThread.getName());//这里打印的会是handler thread
   setTitle("哈哈");//这样必定报错
   //android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
       }
 });
 这样该怎么办呢,呵呵,可以无参构建一个handler。用这个handler来发送消息和处理消息,用上面的handler来开启新线程。
 mainHandler = new Handler(){
   protecket void handlerMessage(Message msg){
     setTitle("哈哈");//这样就不会报错啦
   }
 }
 handler.post(new Runnable(){//这里run()方法其实还是在等ht.start()调用
   public void run(){
   Log.e("当前线程:",Thread.currrentThread.getName());//这里打印的会是handler thread
   mainHandler.sendEmpetMessage();//用mainHandler来发送消息
   //setTitle("哈哈");//这样必定报错
   //android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
       }
 });

打印Log:


android多线程先后执行 android多线程处理_主线程

3.其实第2个方法显得麻烦而且低效,用了2个handler,一个用来发起线程,一个用于处理消息。发起线程的handler必须拥有looper,所以还要实例化一个HanderThread;而处理消息的handler则不需要looper,因为它默认拥有主线程的looper,所以可以在这个handler处理ui。

其实可以只需要实例化一个handler,在主线程里构建一个无参的handler,然后由它发送和处理消息。而创建线程的任务就不用handler了,直接用new Thread(r).start();然后在r的run()方法里面处理逻辑事务。

用这样的模式下载5张图片,你就可能不会看到图片一张挨着一张展示出来,可能第2张先出来,也可能同时出来3张,5条线程很随机的。

private void loadImagesByThread(final String url,final int id){//通过Thread来new 出多个线程
         
         new Thread(new Runnable(){

             @Override
             public void run() {
                 // TODO Auto-generated method stub
                 Log.e("当前线程:", ""+Thread.currentThread().getName());
                 Drawable drawable = null;
                 try {
                     drawable = Drawable.createFromStream(new URL(url).openStream(), "image.gif");
                 } catch (MalformedURLException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 } catch (IOException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
                 Message msg = mainHandler.obtainMessage();
                 msg.what = 2012;
                 msg.arg1 = id;
                 msg.obj = drawable;
                 msg.sendToTarget();
                 
             }
             
         }).start();
     }

打印Log:


android多线程先后执行 android多线程处理_实例化_02