频道栏目
首页 > 资讯 > Android > 正文

Android多线程更新UI的方式

14-09-14        来源:[db:作者]  
收藏   我要投稿
Android下,对于耗时的操作要放到子线程中,要不然会残生ANR,本次我们就来学习一下Android多线程更新UI的方式。
 
  首先我们来认识一下anr:
 
  anr:application not reponse:应用程序无响应
  主线程:UI线程
  anr产生的原因:主线程需要做很多重要的事情,响应点击事件,更新ui,如果在主线程里面阻塞时间过久,应用程序就会无响应,为了避免应用程序出现anr,所有的耗时的操作,都应该放在子线程中执行。
 
  认识了anr后,我们就来学习一下怎样在Android下开启多线程,并更新ui了。一共有两种方式:
 
第一种采用:Handler。
 
  Handler获取当前线程中的looper对象,looper用来从存有Message的Message Queue里取出message,再由Handler进行message的分发和处理。
 
handler进制的原理:
 
  android提供了handler和looper来满足线程间的通信。Handler先进先出原则。looper用来管理特定线程内对象之间的消息交换(message Exchange).
 
     1)looper:一个线程可以产生一个looper对象,由它来管理此线程里的message queue(消息队列)
 
      2)handler:你可以构造一个handler对象来与looper沟通,以便push新消息到messagequeue里;或者接收looper(从messagequeue里取出)所送来的消息。
 
我们使用的时候呢,需要在子线程中定义message,并把要返回的obj对象,传递给msg,同时由于handler不止要处理这一种类型,所以我们还要定义what的类型,以便让handler分类处理。
 
 
Message msg = new Message();
msg.what = CHANGE_UI;
msg.obj = result;
handler.sendMessage(msg);
 
 
好的接下来我们就实例来使用handler。
 
new Thread(){
    public void run() {
        try {
         URL url = new URL(path);
         HttpURLConnection conn = (HttpURLConnection) url.openConnection();
         conn.setRequestMethod("GET");
         conn.setConnectTimeout(5000);
         conn.setRequestProperty("User-Agent", "");
          
         int code = conn.getResponseCode();
         if(code==200){
             InputStream is = conn.getInputStream();
             String result = StreamTools.readInputStream(is);
              
             //tv_content.setText(result);
             Message msg = new Message();
             msg.what = CHANGE_UI;
             msg.obj = result;
             handler.sendMessage(msg);
              
              
         }else{
             Message msg = new Message();
             msg.what = ERROR;
             handler.sendMessage(msg);
         }
          
     } catch (Exception e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
          
         Message msg = new Message();
         msg.what = ERROR;
         handler.sendMessage(msg);
          
          
     }
         
         
    };
}.start();
 这里采用的 StreamTools.readInputStream的实现是这样的,目的是把输入流转化为字符串。
 
 
/**
     * 把输入流转化为字符串
     * @param is
     * @return
     */
    public static String readInputStream(InputStream is){
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int len = 0;
            byte[] buffer = new byte[1024];
            while((len = is.read(buffer))!=-1){
                baos.write(buffer,0,len);
            }
            is.close();
            baos.close();
            byte[] result = baos.toByteArray();
             
            //试着解析网址返回的字符串,
            String temp = new String(result);
            if(temp.contains("utf-8")){
                return temp;
            }else if(temp.contains("gbk")){
                return new String(result,"gbk");
            }
             
            return temp;
            //return new String(result);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return "获取失败";
        }
         
    }
 
 
其中handler的实现是这样的。
 
 
private Handler handler = new Handler(){
    public void handleMessage(android.os.Message msg) {
        switch (msg.what) {
        case ERROR:
            Toast.makeText(MainActivity.this, "获取数据失败", 0).show();
            break;
        case CHANGE_UI:
            tv_content.setText(msg.obj+"");
            Toast.makeText(MainActivity.this, "获取数据失败", 0).show();
            break;
 
        }
    };
};
 这样呢,我们便可以用handler,也即消息处理机制来更新UI了,
 
 
 
第二种方式。
 
  采用runOnUiThread(new Runnable()),这要实现Runnable借口,我们可以直接在这个线程中进行UI的更新。是api提供的方法,较为便捷。
 
  
 
new Thread(){
        @Override
        public void run() {
            final String result = LoginServices.loginByGet(username, password);
            if(result != null){
                //成功
                runOnUiThread(new Runnable() {
                     
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        Toast.makeText(MainActivity.this, result, 0).show();
                    }
                });
            }else{
                //请求失败
                runOnUiThread(new Runnable() {
                     
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        Toast.makeText(MainActivity.this, "请求失败", 0).show();
                    }
                });
            }
             
        };
    }.start();
相关TAG标签
上一篇:算法之插入排序
下一篇:IOS 解析歌词lrc
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站