android handler
来源:互联网 发布:apache压力测试 编辑:程序博客网 时间:2024/06/05 07:26
以下文字 摘自 老罗的 源代码分析一书
Android 应用程序都是通过消息来驱动的。Android 应用程序的每一个线程在启动时,都可以首先在内部创建一个消息队列,然后进入到一个无线循环中,不断检查它的消息队列是否有新的消息需要处理。如果有新的消息需要处理,那么线程就会将它从消息队列中取出来,并且对它进行处理;否则,线程就会进入睡眠等待状态,直到有新的消息需要处理为止。这样就可以通过消息来驱动Android应用程序的执行了。
Android应用程序的消息处理机制是围绕消息队列来实现的。一个线程拥有了一个消息队列之后,就可以进入到一个消息循环中,同时 其他线程以及线程本身 可以往这个消息队列发送消息。
Android系统主要通过MessageQueue、Looper和Handler三个类来实现Android 应用程序的消息处理机制,其中,MessageQueue类用来描述消息队列;Looper 类用来创建消息队列,以及消息的轮询 。Handler类用来发送和处理消息。
java层 Looper 对象内都有一个MessageQueue类型的成员变量mQueue ,它指向一个MessageQueue对象。
通过Looper.prepare()或Looper.prepareMainLooper()来创建。注意 Looper类的静态成员函数prepareMainLooper 只能在Android 主线程中调用。但是主线程的Looper对象保存在一个独立的静态成员变量中,这样可以让其他线程通过Looper类的静态成员函数getMainLooper 来访问它,从而可以向从属于主线程looper对象的messageQueue消息队列里发送一些与ui操作相关的message啦!
prepare 时 就会创建一个包含有指向MessageQueue对象的变量的Looper对象
read the fucking source code
ActivityThread main 方法
public static void main(String[] args) { SamplingProfilerIntegration.start(); // CloseGuard defaults to true and can be quite spammy. We // disable it here, but selectively enable it later (via // StrictMode) on debug builds, but using DropBox, not logs. CloseGuard.setEnabled(false); Environment.initForCurrentUser(); // Set the reporter for event logging in libcore EventLogger.setReporter(new EventLoggingReporter()); Security.addProvider(new AndroidKeyStoreProvider()); Process.setArgV0("<pre-initialized>"); Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } AsyncTask.init(); if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
public static void prepare() { prepare(true); } private static void prepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); }
public static void prepareMainLooper() { prepare(false); synchronized (Looper.class) { if (sMainLooper != null) { throw new IllegalStateException("The main Looper has already been prepared."); } sMainLooper = myLooper(); } }
public final class MessageQueue { // True if the message queue can be quit. private final boolean mQuitAllowed;主线程的消息队列不可以被终止
private Looper(boolean quitAllowed) { mQueue = new MessageQueue(quitAllowed); mThread = Thread.currentThread(); }可以看到looper类的构造方法里 有创建MessageQueue对象
handler.sendmessage/sendemptymessage ---> sendMessageAtTime
public boolean sendMessageAtTime(Message msg, long uptimeMillis) { MessageQueue queue = mQueue; if (queue == null) { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); return false; } return enqueueMessage(queue, msg, uptimeMillis); }
Looper.looper() 无限轮询 while(true) or for(,,)
public static void loop() { final Looper me = myLooper(); if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue;--------------- for (;;) { Message msg = queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; } ------ =------ } msg.target.dispatchMessage(msg);------ msg.recycle(); } }
msg.target 是对应的handler
handler的dispatchMessage()方法
public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
子线程中创建Handler
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);tv = new TextView(this);tv.setGravity(Gravity.CENTER);tv.setText("lalalala");tv.setTextColor(Color.BLACK);setContentView(tv);Log.i(TAG, "thread currendthread :: " + Thread.currentThread());//thread = new MyThread();//thread.start();//thread.handler.sendEmptyMessage(0);//NullPointExceptionHandlerThread thread = new HandlerThread("childThreadName");thread.start();Handler childHandler = new Handler(thread.getLooper()){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);Log.i(TAG, "current thread :: "+Thread.currentThread());}};childHandler.sendEmptyMessage(0);
<span style="white-space:pre">thread.quit();</span>//Quits the handler thread's looper.
}class MyThread extends Thread {public Handler handler ;@Overridepublic void run() {Looper.prepare();handler = new Handler(){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);Log.i(TAG, "current thread :: "+Thread.currentThread());}};Looper.loop();/*tv.post(new Runnable() {@Overridepublic void run() {tv.setText("success");}});*//*runOnUiThread(new Runnable() {@Overridepublic void run() {tv.setText("success");}});*/}}HandlerThread 不用担心空指针异常 是因为 它的getLooper方法
public Looper getLooper() { if (!isAlive()) { return null; } // If the thread has been started, wait until the looper has been created. synchronized (this) { while (isAlive() && mLooper == null) { try { wait(); } catch (InterruptedException e) { } } } return mLooper; }
直到 run 方法 执行到looper 对象初始化 唤醒
@Override public void run() { mTid = Process.myTid(); Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); mTid = -1; }handler callback 与 removeMessages
if (tvThread == null){tvThread = new Runnable(){int index = -1;String[] s = new String[]{ " 正在努力加载-", " 正在努力加载- -", " 正在努力加载- - -" };@Overridepublic void run(){index++;index = index % 3;tvNames.setText(s[index]);handler.postDelayed(tvThread, 300);}};}handler.postDelayed(tvThread, 100);
handler.removeCallbacks(tvThread);//结束thread
private Handler handler = new Handler(new Handler.Callback(){@Overridepublic boolean handleMessage(Message msg){if (isFinish){return true;//不再回调 下面的handleMessage方法}return false;}}){@Overridepublic void handleMessage(Message msg){
mHandler.removeMessages(0, null);
Remove any pending posts of messages with code 'what' and whose obj is 'object' that are in the message queue. Ifobject is null, all messages will be removed.
/** * Handle system messages here. */ public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
public final class Message implements Parcelable { public int what; public int arg1; public int arg2; public Object obj; /*package*/ int flags; /*package*/ long when; /*package*/ Bundle data; /*package*/ Handler target; /*package*/ Runnable callback; // sometimes we store linked lists of these things /*package*/ Message next;
private static void handleCallback(Message message) { message.callback.run(); }
public interface Callback { public boolean handleMessage(Message msg); }
未完待续---
Multiple dex files define ------jar包 support v7 v4 版本不一致导致
- android Handler
- android Handler
- android Handler
- android Handler
- Android Handler
- android---handler
- android-handler
- Android Handler
- Android Handler
- Android Handler
- android Handler
- android--Handler
- Android Handler
- Android Handler
- Android Handler
- Android Handler
- Android handler
- Android Handler
- apache虚拟主机
- unity 实现炸弹人放炸弹后只进不出的一种方法
- 防火墙Iptable与Ebtable中的RETURN
- newgrp命令
- 今天做项目遇到要定位到当前的城市百度地图
- android handler
- 汇编 DOS系统功能调INT 21H
- flume-ng 实际应用例子,flume采集log4j日志
- 最全的常用正则表达式大全——包括校验数字、字符、一些特殊的需求等等
- ITween
- 动态迁移
- React 入门实例教程
- php配置导致的页面编码问题
- AFNetworking中operation的使用