学习Looper,handle后感
来源:互联网 发布:java类初始化过程 编辑:程序博客网 时间:2024/04/29 08:19
从老罗那里学习了相关知识后,自己跟随6.0的源码学习一遍。此处只为记录自己的感想和见解,有错误之处望大家指正!!!谢谢各位看官!
总体分为以下3个步骤:
1、消息循环
2、消息发送
3、消息接收处理
1、消息循环
一、初始化
Process.setArgV0("<pre-initialized>"); ................. Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } // End of event ActivityThreadMain. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); Looper.loop();
省略了不少无关代码。上面的代码初始化和looper ,得到了一个ActivityThread.下面具体看看代码。
frameworks/base/core/java/android/os/Looper.java
Looper.prepareMainLooper(),具体代码如下:
/** * Initialize the current thread as a looper, marking it as an * application's main looper. The main looper for your application * is created by the Android environment, so you should never need * to call this function yourself. See also: {@link #prepare()} */ public static void prepareMainLooper() { prepare(false); synchronized (Looper.class) { if (sMainLooper != null) { throw new IllegalStateException("The main Looper has already been prepared."); } sMainLooper = myLooper(); } }
/** * Return the Looper object associated with the current thread. Returns * null if the calling thread is not associated with a Looper. */ public static @Nullable Looper myLooper() { return sThreadLocal.get(); }
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)); }
private Looper(boolean quitAllowed) { mQueue = new MessageQueue(quitAllowed); mThread = Thread.currentThread(); }
相关代码已经贴出来,6.0版本和2.3并没有什么区别。 这里将一个looper对象设置为唯一的主线程的looper用
sThreadLocal保存,是对象内的变量。这里quitAllowed=false。然后初始化了一个messageQueue.下面看下这个消息队列:处于同一目录
MessageQueue(boolean quitAllowed) { mQuitAllowed = quitAllowed; mPtr = nativeInit(); }这里调用了JNI,
static jlong android_os_MessageQueue_nativeInit(JNIEnv* env, jclass clazz) { NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue(); if (!nativeMessageQueue) { jniThrowRuntimeException(env, "Unable to allocate native queue"); return 0; } nativeMessageQueue->incStrong(env); return reinterpret_cast<jlong>(nativeMessageQueue);}
这里将生成的nativeMessageQueue进行了加工,返回给java层,用ptr 保存了这个对应关系。下面贴下如何new NativeMessageQueue()
NativeMessageQueue::NativeMessageQueue() : mPollEnv(NULL), mPollObj(NULL), mExceptionObj(NULL) { mLooper = Looper::getForThread(); if (mLooper == NULL) { mLooper = new Looper(false); Looper::setForThread(mLooper); }}Looper目录在:system/core/libutils/Looper.cpp 注意大小写区分
Looper::Looper(bool allowNonCallbacks) : mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false), mPolling(false), mEpollFd(-1), mEpollRebuildRequired(false), mNextRequestSeq(0), mResponseIndex(0), mNextMessageUptime(LLONG_MAX) { mWakeEventFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); LOG_ALWAYS_FATAL_IF(mWakeEventFd < 0, "Could not make wake event fd: %s", strerror(errno)); AutoMutex _l(mLock); rebuildEpollLocked();}
void Looper::rebuildEpollLocked() { // Close old epoll instance if we have one. if (mEpollFd >= 0) {#if DEBUG_CALLBACKS ALOGD("%p ~ rebuildEpollLocked - rebuilding epoll set", this);#endif close(mEpollFd); } // Allocate the new epoll instance and register the wake pipe. mEpollFd = epoll_create(EPOLL_SIZE_HINT); LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance: %s", strerror(errno)); struct epoll_event eventItem; memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union eventItem.events = EPOLLIN; eventItem.data.fd = mWakeEventFd; int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeEventFd, & eventItem); LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake event fd to epoll instance: %s", strerror(errno)); for (size_t i = 0; i < mRequests.size(); i++) { const Request& request = mRequests.valueAt(i); struct epoll_event eventItem; request.initEventItem(&eventItem); int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, request.fd, & eventItem); if (epollResult < 0) { ALOGE("Error adding epoll events for fd %d while rebuilding epoll set: %s", request.fd, strerror(errno)); } }}
2、消息发送
3、消息接收处理
0 0
- 学习Looper,handle后感
- Handle和Looper
- handle message looper messagequeue
- 关于looper,handle,messageQuerry
- Handle、Message、Looper
- Looper、handle、Message图文详解
- android handle looper 使用误区
- handle message Looper源码解析
- Android Handle机制 理解Looper、Handle、Message的关系
- Message,Handle,Looper之间的关系
- 3 获取质数 Handle Bundle Looper
- Android Handle,Looper,Message消息机制
- Android线程中消息处理(Handle,Looper)
- Handle、Looper与Message之间的关系
- Handle MessageQueue Message Looper之间的关系
- android handle学习笔记
- JAVA学习---HANDLE EVENT
- Android学习之Handle
- Android 打aar架包
- Android KeyCode列表
- 开发拓展之单例设计模式
- 【数据库管理工具】Navicat安装及使用教程
- HDU 1571 下沙小面的 vector应用
- 学习Looper,handle后感
- Codeforces Round #332 (Div. 2)-C. Day at the Beach
- kettle日志参数设置
- shell脚本学习之语法
- java基础_面向对象总结
- 少年,加油吧
- LightOJ 1112
- 图结构练习——最短路径
- poj1266Cover an Arc.(三角形的外心)