`

Handler Runnable Demo 学习

阅读更多
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<TextView android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:layout_gravity="center"
		android:id="@+id/txt" />
	<Button android:id="@+id/btnStartTime" android:text="开始计时"
		android:layout_width="80dip" android:layout_height="wrap_content"></Button>
	<Button android:id="@+id/btnStopTime" android:text="停止计时"
		android:layout_width="80dip" android:layout_height="wrap_content" />
	<SeekBar android:layout_height="wrap_content"
		android:layout_width="fill_parent" android:id="@+id/SeekBar01"></SeekBar>
</LinearLayout>


本例子通过Thread来模拟Handler的功能,利用Thread.sleep(1000)来
模拟1seconds,而每隔1s,Handler都会将当前剩余时间发到消息队列中,
Handler的构造函数之一Handler(Handler.CallBack),实现Handler.CallBack
中的handleMessage方法就能够获取Handler发出的消息。

HandlerExampleActivity01.java
package kping.example;
 
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
 
public class HandlerExampleActivity01 extends Activity implements
        Handler.Callback, Button.OnClickListener {
    final static String TAG = "HandlerExampleActivity01";
    TextView txt;
    Button btnStart;
    Button btnStop;
    Handler myHandler;
    TimerThread timerThread;
    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        setupView();
    }
    public void setupView() {
        txt = (TextView) findViewById(R.id.txt);
        btnStart = (Button) findViewById(R.id.btnStartTime);
        btnStop = (Button) findViewById(R.id.btnStopTime);
        btnStart.setOnClickListener(this);
        btnStop.setOnClickListener(this);
        // Handler的构造函数之一Handler(Handler.Callback callback),所以HandlerExampleAcitivity01要实现
        //Handler.CallBack,从而实现handleMessage
        myHandler = new Handler(this);
        //打印主线程的id号
        Log.d(TAG, "ThreadId:" + String.valueOf(Thread.currentThread().getId()));
    }
 
    //     implements Handler.CallBack
    public boolean handleMessage(Message msg) {
        switch (msg.what) {
        case 0:
            Bundle data = msg.getData();
            txt.setText(String.valueOf(data.getInt("time")));
 
            Log.d("ThreadId",
                "HandleMessage:"
                            + String.valueOf(Thread.currentThread().getId()));
            Log.d("ThreadId", "msgData:" + String.valueOf(data.getInt("time")));
            break;
        }
        return false;
    }
 
    //  implements Button.OnClickListener
    public void onClick(View view) {
        switch (view.getId()) {
        case R.id.btnStartTime:
            timerThread = new TimerThread(myHandler, 60);
            timerThread.start();
            break;
        case R.id.btnStopTime:
            timerThread.stop();
            break;
        }
    }
 
}


TimerThread.java
 
package kping.example;
 
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
 
public class TimerThread extends Thread {
    private final static String TAG = "TimerThread";
	private Handler handler;
	private int total;
 
	public TimerThread(Handler handler, int total) {
		this.handler = handler;
		this.total = total;
	}
 
	public void run() {
		while (true) {
			if(total < 0) 
				break;
			Message msg = new Message();
			Bundle data = new Bundle();
			data.putInt("time", total);
			msg.setData(data);
			msg.what = 0;
			Log.d(TAG, "ThreadId:" + String.valueOf(Thread.currentThread().getId()));
			handler.sendMessage(msg);
			try {
				sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			total--;
		}
	}
}



黄条是检测当前UI是否阻塞,后面有用到

ps:
这里stop按钮不起作用,可以给他设置个flag=false,需要添加一下逻辑,
另外start多按几下,logcat相应也会多出几个线程,程序要完善点,就对
timerThread添加些逻辑,若为null,才新建对象。不过这些不是重点,handler
大概意思传递到了就好

Scheduling messages is accomplished with the post(Runnable), postAtTime(Runnable, long), postDelayed(Runnable, long), sendEmptyMessage(int), sendMessage(Message), sendMessageAtTime(Message, long), and sendMessageDelayed(Message, long) methods. The post versions allow you to enqueue Runnable objects to be called by the message queue when they are received; the sendMessage versions allow you to enqueue a Message object containing a bundle of data that will be processed by the Handler's handleMessage(Message) method (requiring that you implement a subclass of Handler).

上述字段摘自API中Handler的类说明
大致意思:可以有post(Runnable) sendMessage(Message)两种方法传递信息,其他都是在此基础上添加时间限制

下面再来一个例子,这里我们用内部类来实现Handler,所以不需要实现Handler.CallBack.当然post(Runnable)暗示主类要实现Runnable,与刚刚例子相比可以将TimerThread类撤掉,将记时功能也移至主类当中

HandlerExampleActivity02.java
package kping.example;
 
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
 
public class HandlerExampleActivity02 extends Activity implements
        Button.OnClickListener{
    private final static String TAG = "HandlerExampleActivity02";
    private TextView txt;
    private Button btnStart;
    private Button btnStop;
    private int total = 8;
    private final Handler myHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case 0:
                Bundle data = msg.getData();
                txt.setText(String.valueOf(data.getInt("time")));
                Log.d(TAG, data.getInt("time") + "");
                break;
            }
        }
    };
 
    private final Runnable runnable = new Runnable() {
 
        @Override
        public void run() {
            while (true) {
                if (total < 0)
                    break;
                Message msg = new Message();
                Bundle data = new Bundle();
                data.putInt("time", total);
                msg.setData(data);
                msg.what = 0;
                myHandler.sendMessage(msg);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                total--;
            }
        }
    };
 
    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        setupView();
    }
 
    public void setupView() {
        txt = (TextView) findViewById(R.id.txt);
        btnStart = (Button) findViewById(R.id.btnStartTime);
        btnStop = (Button) findViewById(R.id.btnStopTime);
        btnStart.setOnClickListener(this);
        btnStop.setOnClickListener(this);
    }
 
    public void onClick(View view) {
        switch (view.getId()) {
        case R.id.btnStartTime:
            myHandler.post(runnable);   //触发run()
            break;
        case R.id.btnStopTime:
            myHandler.removeCallbacks(runnable);
            break;
        }
    }
}


之前我运行这个例子的时候一度以为出问题了,其实Thread.sleep()把主线程给睡了,把total设为60直接force close,令total=10还行,不过textView不会显示10,9,8.....而是10秒后直接显示0;logcat也是在10s后将10,9....0打印出来。这个例子其实可以优化,下面是我网上看到的一个例子。

HandlerExampleActivity03.java
package kping.example;
 
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
 
public class HandlerExampleActivity03 extends Activity {
    /** Called when the activity is first created. */
    private Button butStart;
    private Button butStop;
    TextView tv;
    int i = 0;
    Handler handler = new Handler();
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // Handler在那个Activity中new的就且仅属于那个Activity的
        butStart = (Button) findViewById(R.id.btnStartTime);
        butStop = (Button) findViewById(R.id.btnStopTime);
        tv = (TextView) findViewById(R.id.txt);
        butStart.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                handler.post(runnable);
            }
        });
        butStop.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                handler.removeCallbacks(runnable);
            }
        });
    }
 
    Runnable runnable = new Runnable() {
        public void run() {
            tv.setText(String.valueOf(i++));
            handler.postDelayed(runnable, 1000);
        }
    };
}


这个例子很清爽,之前用计数器弱爆了..
0
1
分享到:
评论

相关推荐

    android demo,使用Runnable和Handler的特性实现每个3s的定时器

    android demo,使用Runnable和Handler的特性实现每个3s的定时器

    android demo,使用Handler的postDelay,Runnable run实现延时3秒的splash。

    android demo,使用Handler的postDelay,Runnable run实现延时3秒的splash。

    Android开发笔记之:Handler Runnable与Thread的区别详解

    在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口;Thread类是在java.lang包中定义的。一个类只要继承了Thread类同时覆写了本类中的run()方法就可以实现多线程操作了,但是一个类只能...

    android 简单的摇奖demo

    android 摇奖 随机数 handler Runnable tabhost的应用 很有帮助的

    ViewSwitcher Demo轮回播放图片

    主要技术点:ViewSwitcher(它只能添加两个子view,有兴趣的可以修改源码,继承使用,使它支持更多的视图,但不建议这么做),另外就是handler调用runnable了。有兴趣的下载下吧,本例只收你1分!

    每隔5秒改变一次背景色

    启动子线程发送更新消息,然后使用Handler的子类,重写handleMessage(Message msg)方法 效果:每隔5秒改变一次背景色 ...使用:将下载的HandlerDemo.png格式图片后缀改为HandlerDemo.zip,解压即可得到源码

    Android动画与定位Demo

    主要内容: 1、三、二、一、GO动画效果 2、加载中等待动画效果 3、定位 4、利用handler中的删除Runnable方法,可使多次点击请求只执行最后一次。

    应用启动页自定义跳转计时器View Demo

    应用启动页自定义跳转计时器View Demo: CircleTextProgressbar.java: package com.demo.startpageskiptimerdemo.widget; import android.content.Context; import android.content.res.ColorStateList; import ...

    仿Launcher的GridView拖动.zip

    2、手指按下的时候使用Handler和Runnable来实现一个定时器,假如定时时间为1000毫秒,在1000毫秒内,如果手指抬起了移除定时器,没有抬起并且手指点击在GridView的item所在的区域,则表示我们长按了GridView的item ...

    Android闪屏效果实现方法

    android的实现非常简单,使用Handler对象的postDelayed方法就可以实现。在这个方法里传递一个Runnable对象和一个延迟的时间。该方法实现了一个延迟执行的效果,延迟的时间由第2个参数指定,单位是毫秒。第一个参数是...

    Google Android sdk 开发范例大全 部分章节代码

    4.17 后台程序运行进度提示——ProgressBar与Handler的整合应用 4.18 动态文字排版——GridView与ArrayAdapter设计 4.19 在Activity里显示列表列表——ListView的布局 4.20 以动态列表配置选项——ListActivity与...

    jfinalpluginsjfinal-dreampie.zip

    public class AttackHandler extends Handler {  @Override  public void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {  request ...

Global site tag (gtag.js) - Google Analytics