zoukankan      html  css  js  c++  java
  • Android Thread Handler UIHandler demos

    extends:http://blog.csdn.net/superjunjin/article/details/7540064

    序效果:为了显示如何用message传值的简单例子

    例1,点击按钮,持续显示当前系统时间(bundle传值,耗时,效率低)

    例2,点击按钮,progressbar持续前进(message方法传值,效率高,但只能传整型int和对象object)

    例1,主activity 

     
    package com.song;  
      
    import java.text.SimpleDateFormat;  
    import java.util.Date;  
      
    import android.app.Activity;  
    import android.os.Bundle;  
    import android.os.Handler;  
    import android.os.Message;  
    import android.view.View;  
    import android.view.View.OnClickListener;  
    import android.widget.Button;  
    import android.widget.TextView;  
      
    public class C91_HandlerActivity extends Activity {  
        /** Called when the activity is first created. */  
        TextView textview;  
        Button button;  
        MyThread mythread;  
        Thread thread;  
        MyHandler handler;  
        @Override  
        public void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.main);  
            textview=(TextView)findViewById(R.id.textview);  
            button=(Button)findViewById(R.id.button);  
            handler=new MyHandler();  
            button.setOnClickListener(new OnClickListener() {  
                  
                @Override  
                public void onClick(View v) {  
                    // TODO Auto-generated method stub  
                    mythread=new MyThread();  
                    thread=new Thread(mythread);  
                    thread.start();  
                }  
            });  
        }  
        class MyHandler extends Handler  
        {  
            //接受message的信息  
            @Override  
            public void handleMessage(Message msg) {  
                // TODO Auto-generated method stub  
                super.handleMessage(msg);  
                if(msg.what==1)  
                {  
                    textview.setText(msg.getData().getString("time"));  
                }  
                  
            }  
        }  
        class MyThread implements Runnable  
        {  
      
            @Override  
            public void run() {  
                // TODO Auto-generated method stub  
                while(true)  
                {  
                    try {  
                        Thread.sleep(1000);  
                        String time=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date());  
                        System.out.println(time);  
                        Message message=new Message();  
                        Bundle bundle=new Bundle();  
                        bundle.putString("time", time);  
                        message.setData(bundle);//bundle传值,耗时,效率低  
                        handler.sendMessage(message);//发送message信息  
                        message.what=1;//标志是哪个线程传数据  
                        //message有四个传值方法,  
                        //两个传int整型数据的方法message.arg1,message.arg2  
                        //一个传对象数据的方法message.obj  
                        //一个bandle传值方法  
      
                    } catch (InterruptedException e) {  
                        // TODO Auto-generated catch block  
                        e.printStackTrace();  
                    }  
                }  
            }  
              
        }  
    }  

    布局文件

      

    <?xml version="1.0" encoding="utf-8"?>  
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
        android:layout_width="fill_parent"  
        android:layout_height="fill_parent"  
        android:orientation="vertical" >  
    <Button  android:layout_width="fill_parent"  
            android:layout_height="wrap_content"  
            android:text="开始"  
            android:id="@+id/button"/>  
        <TextView  
            android:layout_width="fill_parent"  
            android:layout_height="wrap_content"   
            android:textSize="20dp"  
            android:textStyle="bold"  
            android:id="@+id/textview"/>  
      
    </LinearLayout>  
     

    例2,主activity

      

    package com.song;  
      
    import android.app.Activity;  
    import android.os.Bundle;  
    import android.os.Handler;  
    import android.os.Message;  
    import android.view.View;  
    import android.view.View.OnClickListener;  
    import android.widget.Button;  
    import android.widget.ProgressBar;  
      
    public class C92_Handler2Activity extends Activity {  
        /** Called when the activity is first created. */  
        Button button;  
        ProgressBar bar;  
        MyThread mythread;  
        Thread thread;  
        MyHandler handler;  
        @Override  
        public void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.main);  
            button=(Button)findViewById(R.id.button);  
            bar=(ProgressBar)findViewById(R.id.bar);  
            handler=new MyHandler();  
            button.setOnClickListener(new OnClickListener() {  
                  
                @Override  
                public void onClick(View v) {  
                    // TODO Auto-generated method stub  
                    mythread=new MyThread();  
                    thread=new Thread(mythread);  
                    thread.start();  
                }  
            });     
        }   
        class MyHandler extends Handler  
        {  
            @Override  
            public void handleMessage(Message msg) {  
                // TODO Auto-generated method stub  
                super.handleMessage(msg);  
                if(msg.what==1)  
                {  
                    System.out.println(msg.arg1+"handle");  
                    bar.setProgress(msg.arg1);  
                }  
            }  
        }  
        
        class MyThread implements Runnable  
        {  
            int pro=0;  
            @Override  
            public void run() {  
                // TODO Auto-generated method stub  
                while(true)  
                {  
                    try {  
                        Thread.sleep(1000);  
                        pro=bar.getProgress()+1;  
                        bar.setProgress(pro);   
                        System.out.println(pro+"thread");  
                        Message message=new Message();  
                        message.arg1=pro;  
                        message.what=1;  
                        handler.sendMessage(message);  
                          
                    } catch (InterruptedException e) {  
                        // TODO Auto-generated catch block  
                        e.printStackTrace();  
                    }  
                      
                }  
            }  
              
        }  
         
    }  
     


    布局文件

      

    <?xml version="1.0" encoding="utf-8"?>  
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
        android:layout_width="fill_parent"  
        android:layout_height="fill_parent"  
        android:orientation="vertical" >  
    <Button android:layout_width="fill_parent"  
            android:layout_height="wrap_content"  
            android:id="@+id/button"  
            android:text="开始"  
        />  
        <ProgressBar android:layout_width="fill_parent"  
            android:layout_height="wrap_content"  
            android:id="@+id/bar"  
            style="@android:style/Widget.ProgressBar.Horizontal"  
            />  
      
    </LinearLayout>  

    显示效果

    -------------------------------------------------------------

     extends:http://blog.csdn.net/shenyuemei/article/details/11030679

     在工作线程中处理UI线程报错:Only the original thread that created a view hierarchy can touch its views.

    如果将更新UI控件的代码写入到工作线程中便会报错,

    Runnable socketRun = new Runnable() {  
      
            @Override  
            public void run() {  
                // TODO Auto-generated method stub  
                tv = (TextView) findViewById(R.id.tv);  
                Socket socket = null;  
                String message = et.getText().toString() + "
    ";  
                try {  
                    // 创建socket  
                    socket = new Socket("192.168.1.34", 8080);  
                    // 向服务器发送消息  
                    PrintWriter out = new PrintWriter(new OutputStreamWriter(  
                            socket.getOutputStream()), true);  
                    out.println(message);  
                    // 接收来自服务器的消息  
                    BufferedReader br = new BufferedReader(new InputStreamReader(  
                            socket.getInputStream()));  
                    msgs = br.readLine();  
                    //下面是更新UI的代码,这样写是错误的  
                    if (msgs != null) {  
                        tv.setText(msgs);  
                    } else {  
                        tv.setText("数据错误!");  
                    }  
                    out.close();  
                    br.close();  
                    socket.close();  
                } catch (UnknownHostException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                } catch (IOException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  
            }  
        };  
     

    错误如下:

     android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

    因为这样会阻塞住线程。

    有一下三种改法:

    第一种:利用Message来传递信息给Handler来处理UI的更新问题 

     
    Runnable socketRun = new Runnable() {  
      
            @Override  
            public void run() {  
                // TODO Auto-generated method stub  
                tv = (TextView) findViewById(R.id.tv);  
                Socket socket = null;  
                String message = et.getText().toString() + "
    ";  
                try {  
                    // 创建socket  
                    socket = new Socket("192.168.1.34", 8080);  
                    // 向服务器发送消息  
                    PrintWriter out = new PrintWriter(new OutputStreamWriter(  
                            socket.getOutputStream()), true);  
                    out.println(message);  
                    // 接收来自服务器的消息  
                    BufferedReader br = new BufferedReader(new InputStreamReader(  
                            socket.getInputStream()));  
                    msgs = br.readLine();  
                    <span style="color:#000000;">//实例化message对象  
                    Message msg = new Message();  
                    //给message对象赋值  
                    msg.what = 1;  
                    //发送message值给Handler接收  
                    mHandler.sendMessage(msg);  
    </span>             out.close();  
                    br.close();  
                    socket.close();  
                } catch (UnknownHostException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                } catch (IOException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  
            }  
        };  
      
        <span style="color:#000000;">private Handler mHandler = new Handler() {  
            public void handleMessage(Message msg) {  
                // 更新UI  
                switch (msg.what) {  
                case 1:  
                    if (msgs != null) {  
                        tv.setText(msgs);  
                    } else {  
                        tv.setText("数据错误!");  
                    }  
                    break;  
                }  
      
            };  
        };</span>  

    第二种:利用Handler的post方法 

     
    Runnable socketRun = new Runnable() {  
      
            @Override  
            public void run() {  
                // TODO Auto-generated method stub  
                tv = (TextView) findViewById(R.id.tv);  
                Socket socket = null;  
                String message = et.getText().toString() + "
    ";  
                try {  
                    // 创建socket  
                    socket = new Socket("192.168.1.34", 8080);  
                    // 向服务器发送消息  
                    PrintWriter out = new PrintWriter(new OutputStreamWriter(  
                            socket.getOutputStream()), true);  
                    out.println(message);  
                    // 接收来自服务器的消息  
                    BufferedReader br = new BufferedReader(new InputStreamReader(  
                            socket.getInputStream()));  
                    msgs = br.readLine();  
                      
                    <span style="color:#000000;">mHandler.post(updateThread);  
    </span>               
                    out.close();  
                    br.close();  
                    socket.close();  
                } catch (UnknownHostException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                } catch (IOException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  
            }  
        };  
      
        <span style="color:#000000;">private Handler mHandler = new Handler();  
          
        Runnable updateThread = new Runnable()      
           {     
            
                @Override    
                public void run()     
                {     
                    //更新UI     
                    if (msgs != null) {  
                        tv.setText(msgs);  
                    } else {  
                        tv.setText("数据错误!");  
                    }  
               }     
                     
           };</span>  
     

    第三种方法:官方推荐的方法 

     
    //
    Runnable socketRun = new Runnable() { @Override public void run() { // TODO Auto-generated method stub tv = (TextView) findViewById(R.id.tv); Socket socket = null; String message = et.getText().toString() + " "; try { // 创建socket socket = new Socket("192.168.1.34", 8080); // 向服务器发送消息 PrintWriter out = new PrintWriter(new OutputStreamWriter( socket.getOutputStream()), true); out.println(message); // 接收来自服务器的消息 BufferedReader br = new BufferedReader(new InputStreamReader( socket.getInputStream())); msgs = br.readLine(); <span style="color:#000000;">MainActivity.this.runOnUiThread(updateThread); </span> out.close(); br.close(); socket.close(); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }; <span style="color:#000000;">Runnable updateThread = new Runnable() { @Override public void run() { //更新UI if (msgs != null) { tv.setText(msgs); } else { tv.setText("数据错误!"); } } }; </span>
     
     Runnable socketRun = new Runnable() {  
      
            @Override  
            public void run() {  
                // TODO Auto-generated method stub  
                tv = (TextView) findViewById(R.id.tv);  
                Socket socket = null;  
                String message = et.getText().toString() + "
    ";  
                try {  
                    // 创建socket  
                    socket = new Socket("192.168.1.34", 8080);  
                    // 向服务器发送消息  
                    PrintWriter out = new PrintWriter(new OutputStreamWriter(  
                            socket.getOutputStream()), true);  
                    out.println(message);  
                    // 接收来自服务器的消息  
                    BufferedReader br = new BufferedReader(new InputStreamReader(  
                            socket.getInputStream()));  
                    msgs = br.readLine();  
    MainActivity.this.runOnUiThread(updateThread);   
        out.close();  
                    br.close();  
                    socket.close();  
                } catch (UnknownHostException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                } catch (IOException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  
            }  
        };  
        Runnable updateThread = new Runnable()      
           {     
            
                @Override    
                public void run()     
                {     
                    //更新UI     
                    if (msgs != null) {  
                        tv.setText(msgs);  
                    } else {  
                        tv.setText("数据错误!");  
                    }  
               }     
                     
           };  
  • 相关阅读:
    最小化程序到托盘
    Delphi
    c# 多线程
    下载地址加密
    一个很让我郁闷的java异常
    XmlBeanFactory和ApplicationContext读取spring xml配置文件
    tomcat部署war出错的问题
    JAXB 实现List接口
    Mongo数据模型
    JAXB, Web Services, and Binary Data
  • 原文地址:https://www.cnblogs.com/niray/p/4251377.html
Copyright © 2011-2022 走看看