在android中,一个应用开始运行的时候,系统将创建一个线程名为main,同时也称作UI thread.同一进程中的所有组件都在main线程中创建,并且接收用户的操作.如果阻塞该线程超过5s将弹出ANR对话框。同时android的UI工具包是非线程安全的。

因而有两点必须注意:

1. 不要阻塞UI thread

2. 不要在其它线程中操作UI

也因此推导出两个知识块:

1. 对于需要长时间执行的任务需要启动work thread,在android中启动work thread的方法是什么?

2. 在work thread 如何对UI进行更新和设置


Java传统方法 Thread / Runnable 继承Thread实现run
创建Runnable,实现run,实例作为参数创建Thread


使用Handler进行线程间交互

每一个Handler的实例都与唯一的线程以及该线程的message queue 相关联。

默认情况下handler与创建它的线程相关联,但是也可以在构造函数中传入Looper实例,以绑定到其它线程。

Handler的作用就是将message或runnable对象发送到与之相关联的message queue中,并且从queue中获取他们进行处理。

这就起到了将数据在线程中传递的目的,实现了线程间的交互。

o 对于Handler启动runnable在下面的关于定时和周期性执行中进行详细介绍

o 关联于main线程的handler,实现了帮助work thread 更新UI的目的,在关于在work thread中对UI进行更新和设置中详细介绍

o 为了使handler关联于work thread而非main 线程,需要在构造函数时给定Looper实例

Looper用于执行一个线程的message 循环。通过它handler可以关联上相应的thread及其message queue。默认情况下,thread是没有Looper对象的,需要自己在thread中添加该对象,并调用其 prepare() 和 loop()方法。不考虑同步的情况下简单实现一个有Loop的thread.
其中有2点值得注意:

1. Looper 在调用prepare() 之后才指向当前thread,之前是指向main thread的
2. handler必须在thread调用start方法(运行run)之后才能获取looper,否则为空,因为prepare需要在run方法中调用

o 为了方面使用带有Looper的Thread,android实现了HandlerThread


LoopThread thread1;
public WifiSettings() {
mFilter = new IntentFilter();
mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
mFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
mFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION);
mFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);

mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
handleEvent(intent);
}
};
thread1 = new LoopThread("loopThread");
thread1.start();
mScanner = new Scanner(thread1.MyLooper);

}




class LoopThread extends Thread{
public Looper MyLooper;
public LoopThread(String name) {
super(name);
MyLooper = Looper.myLooper();
Log.w(TAG, "in thread init: loop "
+ MyLooper.getThread().getName()); // main
}

public void run() {
Log.w(TAG, "inthread :" + Thread.currentThread().getName()); // main
Looper.prepare();
MyLooper = Looper.myLooper();
Log.w(TAG, "inthread run: loop " + MyLooper.getThread().getName()); // name
Looper.loop();
}
}

更多相关文章

  1. Android原生Switch控件滑块thumb卡住问题的解决方法
  2. Android开发实践:基于命令模式的异步任务线程
  3. Android 静默安装和智能安装的实现方法
  4. 学习Android线程模型解析(包括UI的更新)
  5. Android Studio——为什么说android UI操作不是线程安全的
  6. Android中Handler的使用方法——在子线程中更新界面
  7. android 使用asynctask结合fragment更新UI(另附线程池管理示例)
  8. Android网络编程之通过Get方法实现
  9. Android中Handler的线程间通讯原理

随机推荐

  1. Android之SharedPreferences两个工具类
  2. Android(安卓)studio的布局总结
  3. android边缓存边播放mp4
  4. Android中的Menu(菜单)的三种类型菜单的
  5. 个人开发总结分享:Android学习及如何利用a
  6. 另一种绕过 Android P以上非公开API限制
  7. Android Training - 使用碎片创建一个动
  8. Android蓝牙通讯模块源码(Android蓝牙开发
  9. [Android Studio 权威教程]Android Studio
  10. 关于Android中GestureOverlayView多笔画