精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (2)
|
|
---|---|
作者 | 正文 |
发表时间:2011-05-28
对于Handler来说,它和与它调用它的Activity是出于同一线程的,上一篇并没有调用线程 上一篇博客里的对Handler的调用时通过Runnable接口来实现的,并且是通过run()方法来启动那个线程的,而且是Activity和Handler是两个线程独立运行的,互补干扰,但是实际情况确实,Activity所在的线程和Handler的线程是同一个线程,下面进行一下实验
package org.hualang.handlertest3; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.util.Log; public class HandlerTest3 extends Activity { private Handler handler = new Handler(); private String TAG = "System.out"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); handler.post(r); setContentView(R.layout.main); //Thread t = new Thread(r); //t.start(); Log.d(TAG,"Activity id:"+Thread.currentThread().getId()); Log.d(TAG,"Activity name:"+Thread.currentThread().getName()); } Runnable r = new Runnable() { public void run() { Log.d(TAG,"Handler id:"+Thread.currentThread().getId()); Log.d(TAG,"Handler name:"+Thread.currentThread().getName()); try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }; }
运行结果: 证明是同一个线程的两个依据: ①Activity的id或name和Handler的id或name是同样的 ②我设置了 handler.post(r); 也就是,如果执行后马上显示文本信息,那么可以证明它们不在同一个线程,但是实际情况是要先执行了handler后5秒,才显示文本信息,说明它们在同一线程
如果将代码改为 //handler.post(r); setContentView(R.layout.main); Thread t = new Thread(r); t.start(); 再次执行,运行结果如下,通过start启动线程,它们不在同一个线程中
---------------------------------------------------------------------------------------------------------------- Looper即循环的从队列当中取得消息的功能,如果在线程中使用Looper Looper很少自己创建,在Android中给出了HandlerThread类,并且具有循环取得并处理消息的功能
下面来实现这种Activity和Handler分别在两个线程中执行,实现真正的异步处理 package org.hualang.handlertest; 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.util.Log; public class HandlerTest4 extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Log.d("System.out","Activity所在线程的id:"+Thread.currentThread().getId()); /** * 生成一个HandlerThread对象,实现了使用Looper来处理消息队列的功能 * 这个类由Android应用程序框架提供 */ HandlerThread handlerThread = new HandlerThread("handlerThread"); handlerThread.start(); MyHandler handler = new MyHandler(handlerThread.getLooper()); Message msg = handler.obtainMessage(); /** * 将Message对象发送到目标对象 * 所谓的目标对象,就是生成该msg对象的handler对象 */ msg.sendToTarget(); } class MyHandler extends Handler { public MyHandler() { } public MyHandler(Looper looper) { super(looper); } public void handleMessage(Message msg) { Log.d("System.out", "handler所在线程的id:"+Thread.currentThread().getId()); } } }
运行结果:
可以看到,Activity和Handler是在两个不同的线程中执行的,这样就是实现了真正的异步处理 1、首先创建一个HandlerThread对象,这个HandlerThread类实现了循环的取得消息并处理 2、用start方法启动一个新线程 3、创建MyHandler类,里面传递的参数即Looper方法所获得的可以循环在队列中取得的消息 4、MyHandler类调用的是带参数Looper的构造方法,并且实现了handlerMessage方法 5、获取一个Message对象 6、将这个对象发送到生成该msg对象的handler对象,从而执行了handleMessage方法
----------------------------------------------------------------------------------------------------- 最后,将说一下Message里传送的数据的使用,这里的msg对象可以使用arg1,arg2或者obj arg1 and arg2 are lower-cost alternatives to using
如果是msg.obj,那么可以这样用 msg.obj = "Welcome to china"; 然后在handleMessage()方法中用 String str = (String)msg.obj;来获得传递的值
如果使用getData()方法的话,需要用到Bundle对象来传递,下面用个例子来说明 Bundle b = new Bundle(); b.putInt("age", 22); b.putString("name", "loulijun"); msg.setData(b); msg.sendToTarget();
上面的代码用来设置要传递的数据 下面的代码用来获取Bundle传递过来的数据并且用Toast来显示 Bundle b = msg.getData(); int age = b.getInt("age"); String name = b.getString("name"); Toast toast = Toast.makeText(getApplicationContext(), "age="+age+"name="+name, Toast.LENGTH_LONG); toast.show();
package org.hualang.handlertest; 运行结果:
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-06-02
以前是搞EE的,现在搞 Andorid 了,lz写的不错,学习了。
|
|
返回顶楼 | |
发表时间:2011-06-22
写得很不错,学习中,
|
|
返回顶楼 | |
发表时间:2011-06-28
火星哥视频里的东西~~讲得木有马士兵好~~
|
|
返回顶楼 | |
发表时间:2011-08-03
让安卓飞一会 写道 火星哥视频里的东西~~讲得木有马士兵好~~
Mars讲的挺好的啊 马士兵有讲android的??? |
|
返回顶楼 | |
发表时间:2011-08-04
最后修改:2011-08-04
hualang 写道
下面来实现这种Activity和Handler分别在两个线程中执行,实现真正的异步处理 package org.hualang.handlertest; 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.util.Log; public class HandlerTest4 extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Log.d("System.out","Activity所在线程的id:"+Thread.currentThread().getId()); /** * 生成一个HandlerThread对象,实现了使用Looper来处理消息队列的功能 * 这个类由Android应用程序框架提供 */ HandlerThread handlerThread = new HandlerThread("handlerThread"); handlerThread.start(); MyHandler handler = new MyHandler(handlerThread.getLooper()); Message msg = handler.obtainMessage(); /** * 将Message对象发送到目标对象 * 所谓的目标对象,就是生成该msg对象的handler对象 */ msg.sendToTarget(); } class MyHandler extends Handler { public MyHandler() { } public MyHandler(Looper looper) { super(looper); } public void handleMessage(Message msg) { Log.d("System.out", "handler所在线程的id:"+Thread.currentThread().getId()); } } }
运行结果: 可以看到,Activity和Handler是在两个不同的线程中执行的,这样就是实现了真正的异步处理 1、首先创建一个HandlerThread对象,这个HandlerThread类实现了循环的取得消息并处理 2、用start方法启动一个新线程 3、创建MyHandler类,里面传递的参数即Looper方法所获得的可以循环在队列中取得的消息 4、MyHandler类调用的是带参数Looper的构造方法,并且实现了handlerMessage方法 5、获取一个Message对象 6、将这个对象发送到生成该msg对象的handler对象,从而执行了handleMessage方法
异步处理消息没有问题,但要注意,涉及到UI界面的更新必须在主线程中处理,别的线程不允许更新UI界面(Toast好像是个例外)。 两外请楼主看下这个http://www.iteye.com/topic/1113067#2222909 希望楼主能有好的解决方式。 |
|
返回顶楼 | |
浏览 8973 次