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() + "\r\n";
            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() + "\r\n";
            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() + "\r\n";
            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() + "\r\n";
            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>
 
时间: 2024-10-24 21:05:14

Android Thread Handler UIHandler demos的相关文章

Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面

Android应用的开发过程中需要把繁重的任务(IO,网络连接等)放到其他线程中异步执行,达到不阻塞UI的效果. 下面将由浅入深介绍Android进行异步处理的实现方法和系统底层的实现原理. 本文介绍Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面: 即如何使用Thread+Handler的方式从非UI线程发送界面更新消息到UI线程. 概述:每个Android应用程序都运行在一个dalvik虚拟机进程中,进程开始的时候会启动一个主线程(MainThread),

Android主线程、子线程通信(Thread+handler)

Android是基于Java的,所以也分主线程,子线程! 主线程:实现业务逻辑.UI绘制更新.各子线程串连,类似于将军: 子线程:完成耗时(联网取数据.SD卡数据加载.后台长时间运行)操作,类似于小兵: 一.子线程向主线程发消息(Thread+handler): 1.主线程中定义Handler: Java代码   Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { super.h

Android开发之异步具体解释(一)Thread+Handler

请尊重他人的劳动成果,转载请注明出处:  Android开发之异步具体解释(一)Thread+Handler http://blog.csdn.net/fengyuzhengfan/article/details/40211589 在Android实际开发project中常常会进行一些诸如:文件读写.訪问网络等耗时的操作,这些耗时的操作是不建议放到UI线程里的. 所以我们会新开一个线程.在子线程中进行这些耗时的操作.耗时操作过程中.UI常常须要更新,但Android是不同意在子线程中改动UI的.

Android中Handler 、Thread和Runnable之间的关系

在多线程编程的时候,我们经常会用到Handler,Thread和Runnable这三个类,我们来看看这三个类之间是怎么样的关系? 首先说明Android的CPU分配的最小单元是线程,Handler一般是在某个线程里创建的,因而Handler和Thread就是相互绑定的,一一对应. 而Runnable是一个接口,Thread是Runnable的子类.可以说,他俩都算一个进程. HandlerThread顾名思义就是可以处理消息循环的线程,他是一个拥有Looper的线程,可以处理消息循环. 与其说H

Android开发之异步详解(一)Thread+Handler

请尊重他人的劳动成果,转载请注明出处:  Android开发之异步详解(一)Thread+Handler http://blog.csdn.net/fengyuzhengfan/article/details/40211589 在Android实际开发工程中经常会进行一些诸如:文件读写.访问网络等耗时的操作,这些耗时的操作是不建议放到UI线程里的.所以我们会新开一个线程,在子线程中进行这些耗时的操作,耗时操作过程中,UI经常需要更新,但Android是不允许在子线程中修改UI的.所以就出现了Th

Android开发之Thread+Handler示例(打地鼠)

直接上代码 package com.mingrisoft; import java.util.Random; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.MotionEvent; import android.view.View; import android.view.View.On

Android中Handler Runnable与Thread的区别详解

原文链接:http://www.codeceo.com/article/android-handler-runnable-thread.html Android中Handler可以异步控制Runnable,那么这样做于Android中的Thread有什么区别呢?本文将通过多个角度来讲解这个问题,读完此文,相信你会对Android中的Handler Runnable与Thread有一个非常全面的了解. 在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:T

Android异步处理系列文章四篇之一使用Thread+Handler实现非UI线程更新UI界面

目录: Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+Looper+MessageQueue深入详解Android异步处理四:AsyncTask的实现原理 Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面 概述:每个Android应用程序都运行在一个dalvik虚拟机进程中,进程开始的时候会启动一个主线程(MainTh

Android异步机制一:使用Thread+Handler实现非UI线程更新UI界面

概述:每个Android应用程序都运行在一个dalvik虚拟机进程中,进程开始的时候会启动一个主线程(MainThread),主线程负责处理和ui相关的事件,因此主线程通常又叫UI线程.而由于Android采用UI单线程模型,所以只能在主线程中对UI元素进行操作.如果在非UI线程直接对UI进行了操作,则会报错: CalledFromWrongThreadException only the original thread that created a view hierarchy can tou