handler 是什么?
handler 就是多线程通信设计的通信方式。Android 是由 Java 封装的。定义启动 APK 运行的主线程为 UI 线程。Android 要求:
1、UI不能做耗时操作(不能阻塞),否则出现 ANR
2、其他线程不做UI操作
java 中的多线程通信方式共同方式:采用阻塞的方式(例如 synchronized,Object类的wait/notify)。因此 Google 重新设计一套 UI 线程和 Work 线程通信的方法:
1、view.post(Runnable action),通过 View 对象引用切换回UI线程
2、activity.runOnUiThread(Runnable action),通过 Avtivity 对象引用切换回UI线程
3、AsyncTask,内部封装了 UI 线程与 Worker 线程切换的操作
4、Handler,异步消息处理
handler 的主要功能及使用方法?
官网 API 接口:https://developer.android.com/reference/android/os/Handler
Handler 传递消息的载体 --- Message(规范数据传输),Message 主要属性:
int what;自定义的标识,用于区分消息
Object obj;传递数据
Handler发送消息类方法:
1.1、boolean sendEmptyMessage (int what)
发送 what 标识的空消息,适用于发通知,不需要传递数据。
1.2、boolean sendMessage (Message msg)
发送一条消息。
2.1、boolean sendEmptyMessageAtTime (int what, long uptimeMillis)
uptimeMillis:系统开机到当前的时间(毫秒)
指定具体时间 uptimeMillis 发送一个 what 标识的空消息。
2.2、boolean sendMessageAtTime (Message msg, long uptimeMillis)
uptimeMillis:系统开机到当前的时间(毫秒),SystemClock.uptimeMillis()可获得。
在具体指定的时间 uptimeMillis 发送一条消息。
3.1、boolean sendEmptyMessageDelayed (int what, long delayMillis)
在经过 delayMillis 毫秒后发送一个 what 标识的空消息。
sendEmptyMessageDelayed(what, 2000) 等价于 sendEmptyMessageAtTime(what, SystemClock.uptimeMillis() + 2000)
3.2、boolean sendMessageDelayed (Message msg, long delayMillis )
从当前时间经过 delayMillis 毫秒后发送一个消息。
Handler处理消息类方法:
1、void handleMessage (Message msg)
须 Override 方法才能接收消息。所有发送的消息都会返回该方法。
Handler切换线程类方法:
1.1、boolean post (Runnable r)
Runnable r会运行在 handler 对象被创建的线程上。若在 UI 线程创建了 Handler 对象,在 Worker 线程调用 handler.post()方法时,Runnable 就会运行 在 UI 线程中。
1.2、boolean postAtTime (Runnable r, long uptimeMillis)
uptimeMillis:系统开机到当前的时间(毫秒)
在具体指定的时间 uptimeMillis 让 Runnable 运行在 Handler 对象被创建的线程中。
1.3、boolean postDelayed(Runnable r, long delayMillis)
从当前时间延迟经过 delayMillis 毫秒后让 Runnable 运行在 Handler 对象被创建的线程中。
小试牛刀
创建handler,并用到handler发送数据及切换到UI线程
public class MainActivity extends AppCompatActivity { TextView mTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView)findViewById(R.id.tv); new WorkThread().start(); } //1、创建Handler对象 Handler mHandler = new Handler(Looper.getMainLooper(),new Handler.Callback(){ @Override public boolean handleMessage(Message msg){ switch(msg.what){ case 1: mTextView.setText("收到空消息"); break; case 2: mTextView.setText("收到指定时间空消息"); break; case 3: mTextView.setText("收到延时空消息"); break; case 4: String data = (String) msg.obj; mTextView.setText("收到消息:" + data); break; } return true; } }); //2、定义工作线程 class WorkThread extends Thread{ @Override public void run(){ super.run(); mHandler.sendEmptyMessage(1); mHandler.sendEmptyMessageAtTime(2, SystemClock.uptimeMillis()+1000); mHandler.sendEmptyMessageDelayed(3,1000); Message mMessage = new Message(); mMessage.what = 4; mMessage.obj = "从工作线程发出的消息"; mHandler.sendMessage(mMessage); mHandler.post(new Runnable() { @Override public void run() { mTextView.setText("通过post,从工作线程切到了UI线程"); } }); } } }