- 浏览: 258730 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (88)
- JAVA / base (26)
- JAVA / web (12)
- JAVA / Lib-tools (5)
- SERVER / tomcat (4)
- DB / mysql (4)
- DB / mongodb (2)
- DB / memcached (2)
- DB / redis (2)
- WEB / Front-end (3)
- WEB / security (4)
- WEB / css (2)
- WEB / js (4)
- OS / linux (3)
- IT / Architecture (4)
- IT / other (2)
- Android (9)
- Go (1)
- Other (1)
- OS / Mac (2)
最新评论
-
Zero2Max:
哈哈,马士兵老师也发现了。
java实现接口的bug -
xly1981:
能像CSRF攻击一样带个图就更棒了
XSS跨站攻击 -
xmong:
df274119386 写道在javascript中看到下面的 ...
CSRF攻击与防御策略 -
df274119386:
在javascript中看到下面的语句 e.value = t ...
CSRF攻击与防御策略 -
xmong:
yzxqml 写道xmong 写道yzxqml 写道tomca ...
Tomcat集群
Android和Handler那些事
目录
1 HANDLER的简单使用 1
2 HANDLER的消息传递 4
3 HANDLER的线程异步 8
1 Handler的简单使用
Handler主要用于异步消息的处理:当调用Handler发送消息方法发出一个消息之后,消息进入一个消息队列,发送消息的方法即刻返回,而Handler的消息处理方法则被调用,逐个的从消息队列中将消息取出,然后对消息进行处理,就是将消息发送和消息处理实现异步化。这种机制通常用来处理相对耗时比较长的操作。
下面通过一个简单的android应用程序来了解Handler的使用
创建一个android应用程序,activity1的实现如下:
运行界面如下:
当点击start按钮时,程序每输出:
start button click!
my thread handler
每隔三秒输出一句:
my thread handler
当点击end按钮后,程序输出:
end button click!
2 Handler的消息传递
上面的例子只是简单handler使用实例,并没有用到handler消息对象来实现消息的异步处理,下面我们来看看怎样利用handler来实现消息异步处理。
基于上面的例子我们可以稍作修改实现一个进度条更新功能。
实现如下:
新创建一个activity实现如下:
新创建一个activity布局文件,activity2.xml
修改AndroidManifest.xml文件
运行程序界面如下:
点击ok按钮后,程序进度条每隔一秒就会更新进度,后台输出如下:
从输出结果我们可以看到,handler的这种消息传递的异步处理都是在id为1的线程中完成整个handler过程,整个过程实际上是单线程处理的,没有真正实现异步化处理,如果要实现handler消息异步化处理可以通过HandlerThread来实现。
3 Handler的线程异步
基于2中的程序稍作修改可以实现Handler的线程异步处理消息功能。
新创建一个activity实现如下:
修改AndroidManifest.xml文件的程序入口为Activity3
运行程序后点击OK按钮,后台输出如下:
从输出结果可以看到activity的主线程id号为1,而消息处理线程的id号为9。整个handler过程由两个线程参与,主线程负责发生消息,而handerThread线程负责处理处理消息。
目录
1 HANDLER的简单使用 1
2 HANDLER的消息传递 4
3 HANDLER的线程异步 8
1 Handler的简单使用
Handler主要用于异步消息的处理:当调用Handler发送消息方法发出一个消息之后,消息进入一个消息队列,发送消息的方法即刻返回,而Handler的消息处理方法则被调用,逐个的从消息队列中将消息取出,然后对消息进行处理,就是将消息发送和消息处理实现异步化。这种机制通常用来处理相对耗时比较长的操作。
下面通过一个简单的android应用程序来了解Handler的使用
创建一个android应用程序,activity1的实现如下:
package com.example; import android.os.Bundle; import android.os.Handler; import android.app.Activity; import android.view.KeyEvent; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class Activity1 extends Activity { //开始按钮 private Button start; //结束按钮 private Button end; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity1); //根据id获取按钮控件 start = (Button)findViewById(R.id.start); end = (Button)findViewById(R.id.end); //给按钮设置事件监听器 start.setOnClickListener(startClick); end.setOnClickListener(endClick); } //点击开始按钮的事件监听器 OnClickListener startClick = new OnClickListener() { @Override public void onClick(View v) { System.out.println("start button click!"); /** * 调用handler的post()方法将线程处理对象放到线程队列中去. * 线程队列中的线程处理对象会被取出执行 */ myHandler.post(myThreadHandler); } }; //结束按钮的事件监听器 OnClickListener endClick = new OnClickListener() { @Override public void onClick(View v) { System.out.println("end button click!"); /** * removeCallbacks()方法与post()方法想反, * 调用该方法可以将线程队列中的线程处理对象移出队列 */ myHandler.removeCallbacks(myThreadHandler); } }; //handler对象 Handler myHandler = new Handler(){}; //线程处理对象 Runnable myThreadHandler = new Runnable() { @Override public void run() { System.out.println("my thread handler"); /** * 调用postDelayed()方法可以定时向线程队列中添加线程处理对象。 * 第一个参数是Runnable类型:将要执行的线程处理对象 * 第二个参数是long类型:延迟的时间,以毫秒为单位 * 即每隔3秒后向线程队列中添加一个线程处理对象 */ myHandler.postDelayed(myThreadHandler, 3000); } }; //按键事件 public boolean onKeyUp(int keyCode, KeyEvent event) { //当按键为回退键是接受这个activity if (keyCode == KeyEvent.KEYCODE_BACK) { Activity1.this.finish(); } return true; }; }
运行界面如下:
当点击start按钮时,程序每输出:
start button click!
my thread handler
每隔三秒输出一句:
my thread handler
当点击end按钮后,程序输出:
end button click!
2 Handler的消息传递
上面的例子只是简单handler使用实例,并没有用到handler消息对象来实现消息的异步处理,下面我们来看看怎样利用handler来实现消息异步处理。
基于上面的例子我们可以稍作修改实现一个进度条更新功能。
实现如下:
新创建一个activity实现如下:
package com.example; import com.example.test_exp_14.R; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.app.Activity; import android.view.KeyEvent; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ProgressBar; public class Activity2 extends Activity { //开始按钮 private Button btn; //进度条 private ProgressBar bar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity2); //根据id获取控件对象 bar = (ProgressBar)findViewById(R.id.bar); btn = (Button)findViewById(R.id.btn); //给开始按钮设置事件监听器 btn.setOnClickListener(btnClick); } //开始按钮事件监听器 OnClickListener btnClick = new OnClickListener() { @Override public void onClick(View v) { System.out.println("main thread id:"+Thread.currentThread().getId()); //将进度条设置为可见 bar.setVisibility(View.VISIBLE); //调用handler的post方法将更新线程对象添加到线程队列中进行处理 updateBarHandler.post(updateThreadHandler); } }; //handler对象 Handler updateBarHandler = new Handler(){ /** * 当消息队列中传入消息时会触发该方法 */ public void handleMessage(Message msg) { //根据msg消息对象来设置进度条当前的进度 bar.setProgress(msg.arg1); /** * 判断进度条当前进度是否达到最大值 * 如果没有达到最大值,则将修改进度条线程对象添加到线程队列中 * 如果达到最大值,则将修改进度条线程对象从线程队列中移出 */ if(msg.arg1 < bar.getMax()){ updateBarHandler.post(updateThreadHandler); }else{ System.out.println("thread id:"+Thread.currentThread().getId()+" process bar end"); updateBarHandler.removeCallbacks(updateThreadHandler); } }; }; //修改进度条线程对象 Runnable updateThreadHandler = new Runnable() { int i = 0; //进度条初始值 int step = 10; //进度条步长 @Override public void run() { //进度条增加步长 i = i+step; System.out.println("thread id:"+Thread.currentThread().getId()+" process bar "+i); //获取handler的消息对象 Message msg = updateBarHandler.obtainMessage(); //将当前进度赋值给msg对象中成员变量保存起来 msg.arg1 = i; try { //程序休息1秒 Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } /** * handler将消息发送到消息队列中, * 当消息发送到消息队列中后,handler会触发handleMessage()方法来处理消息 */ updateBarHandler.sendMessage(msg); } }; //按键事件 public boolean onKeyUp(int keyCode, KeyEvent event) { //当按键为回退键是接受这个activity if (keyCode == KeyEvent.KEYCODE_BACK) { Activity2.this.finish(); } return true; }; }
新创建一个activity布局文件,activity2.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".Activity2" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello"/> <ProgressBar android:id="@+id/bar" style="?android:attr/progressBarStyleHorizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:visibility="gone"/> <Button android:id="@+id/btn" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/ok"></Button> </LinearLayout>
修改AndroidManifest.xml文件
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <!--只需要修改入口程序为com.example.Activity2--> <activity android:name="com.example.Activity2" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
运行程序界面如下:
点击ok按钮后,程序进度条每隔一秒就会更新进度,后台输出如下:
mian thread id:1 thread id:1 process bar 10 thread id:1 process bar 20 thread id:1 process bar 30 thread id:1 process bar 40 thread id:1 process bar 50 thread id:1 process bar 60 thread id:1 process bar 70 thread id:1 process bar 80 thread id:1 process bar 90 thread id:1 process bar 100 thread id:1 process bar end
从输出结果我们可以看到,handler的这种消息传递的异步处理都是在id为1的线程中完成整个handler过程,整个过程实际上是单线程处理的,没有真正实现异步化处理,如果要实现handler消息异步化处理可以通过HandlerThread来实现。
3 Handler的线程异步
基于2中的程序稍作修改可以实现Handler的线程异步处理消息功能。
新创建一个activity实现如下:
package com.example; import com.example.test_exp_14.R; import android.annotation.SuppressLint; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; @SuppressLint("HandlerLeak") public class Activity3 extends Activity{ //开始按钮 private Button btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity2); //根据id获取控件对象 btn = (Button)findViewById(R.id.btn); //给开始按钮设置事件监听器 btn.setOnClickListener(btnClick); } //开始按钮事件监听器 OnClickListener btnClick = new OnClickListener() { @Override public void onClick(View v) { System.out.println(Thread.currentThread().getName()+":"+Thread.currentThread().getId()); /** * 创建handlerThread对象,并启动该对象。 * 只有启动该对象才能通过handlerThread对象中的looper对象,否则获取不到looper对象 */ HandlerThread handlerThread = new HandlerThread("handerThread"); handlerThread.start(); //通过handlerThread的looper对象来创建handler对象 MyHander myHandler = new MyHander(handlerThread.getLooper()); //通过handler对象获取msg对象 Message msg = myHandler.obtainMessage(); /** * bundle可以保存消息传送信息,类似java中的hashmap, * bundle的key只能为string类型,value只能为基本类型和常见的引用类型 */ Bundle bundle = new Bundle(); bundle.putString("name", "xmong"); bundle.putInt("age", 20); //设置msg对象的bundle数据,并将消息发送出去 msg.setData(bundle); msg.sendToTarget(); } }; //内部类handler对象 class MyHander extends Handler{ public MyHander(Looper looper){ super(looper); } /** * 当消息队列中有消息时handler会触发该方法来对消息进行处理 */ @Override public void handleMessage(Message msg) { System.out.println(Thread.currentThread().getName()+":"+Thread.currentThread().getId()); //通过消息对象获取bundle数据 Bundle bundle = msg.getData(); System.out.println("name:"+bundle.getString("name")); System.out.println("age:"+bundle.getInt("age")); } } }
修改AndroidManifest.xml文件的程序入口为Activity3
运行程序后点击OK按钮,后台输出如下:
main:1 handerThread:9 name:xmong age:20
从输出结果可以看到activity的主线程id号为1,而消息处理线程的id号为9。整个handler过程由两个线程参与,主线程负责发生消息,而handerThread线程负责处理处理消息。
发表评论
-
android数据存储之Network
2013-04-24 00:00 1085android数据存储之Network ... -
android数据存储之SDCard
2013-04-24 00:00 1516android数据存储之SDCard 我们都知道androi ... -
android数据存储之ContentProvider
2013-04-23 23:08 2044android数据存储之ContentPr ... -
android数据存储之Sqlite
2013-04-23 23:05 1877android数据存储之Sqlite Sqlite是轻量级的 ... -
android数据存储之Files
2013-04-23 23:03 1484android数据存储之Files Files存储可以通过A ... -
android数据存储之SharedPreferences
2013-04-23 23:01 1466android数据存储之SharedPreferences ... -
android数据存储
2013-04-23 17:55 1316Android的数据存储 在Android中提供了6种数据存 ... -
从java web到android
2013-04-16 15:15 1430几年来一直从事java web的开发,最近组里开始接手一些an ...
相关推荐
android 中Handler 的几种写法,很简单的demo,大神简单修改下,用的是Handler.Callback,的方法
Android的Handler使用方法总结,不错的文档,跟大家分享分享
1.handler是什么? 2.handler怎么用? 3.为什么要用handler?
在Android中使用AsyncTask和Handler线程间交互的方式,详情参见博客:http://www.cnblogs.com/plokmju/p/android_AsyncTask.html和http://www.cnblogs.com/plokmju/p/android_Handler.html
import android.os.Handler; import android.app.Activity; import android.view.Menu; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { ...
Android Handler类详解 Android Handler类详解 Android Handler类详解 Android Handler类详解
Android中handler的使用,处理多线程的使用
android handler的一些测试,套用他人的代码做的一些测试,多个线程sendmessage,该由那个handler处理?
android Handler的使用,我也刚开始学习,从别处下载了给大家分享
Android Handler传值的,简单的介绍了Handler的用法
【Android开发入门】Android线程之Handler
Android中的Handler很重要,但是很简单,学好Handler很重要~
这个资源主要有三个Demo文件 是用来展示Handler的异步处理消息的 第一个Demo展示了如何启动线程和暂停线程 第二个Demo采用了Handler的消息队列机制 第三个Demo用HandlerThread的looper来构造一个handler,然后该...
Android Handler Looper
以前刚接触的Handler的时候,感觉总是很困惑,对Handler原理也是一知半解,现在对Handler知识点总结一下,写了一个Demo,供参考。http://blog.csdn.net/yalinfendou博客中有详细介绍……
android demo,使用Handler的postDelay,Runnable run实现延时3秒的splash。
NULL 博文链接:https://dingran.iteye.com/blog/1930178
Android面试Handler