• Java 中的完毕
    • ThreadLocal
    • MessageQueue
      • 异步音讯和音讯屏障
        • MessageQueue.postSyncBarrier
        • 音讯屏障的消费
        • 异步音讯的效果
    • Looper
    • Handler
    • MessageQueue.IdleHandler
  • Native的完毕
    • MessageQueue
    • Looper#创立epoll作业
    • epoll
    • nativePollOnce
    • nativeWake
    • postDelay的完毕
  • HandlerThread
  • IntentService
  • 参看和问题

大纲

强烈建议看一下Gityuan的文章

  • Handler
  • Looper
  • ThreadLocal
  • MessageQueue
  • HandlerThread
  • IntentService
  • MessageQueue.IdleHandler
    • 《你知道android的MessageQueue.IdleHandler吗?》

简而言之,便是在looper里边的me工程造价ssage暂时处理完了,这个时分会回调这个接口,回来false,那么就会移除它,回来true就会在下次message处理完了的时分继续回调

/**
* Callback interface for discovering when a thread is going to block
* waiting for more messages.
*/
public static interface IdleHandler {
/**
* Called when the message queue has run out of messages and w音讯机制原理ill now
* wait for more.  Return true to keep your idle handler active, false
* to have it removed.  This may be called if there are still messages
* pending in the queue, but they are al链表l scheduled to be dispatched
* after the currjson解析ent ti链表是选用链式存储结构的线性表me.
*/
boolean queueIdlejson();
}

Jjson数据ava 中的完毕

涉及到的4个类:

  • Handler
  • Looper
  • ThreadLocal
  • MessageQueue

Handler面试必会知识点

ThreadLocal

每个线程指针变量链表结构一些和自己相关的变量,ThreadLocal的效果便是保存这些变量的google。一切的变量是经过内部的静态类Value存储的。尽管,线程都是经过访问相同的ThreadLo工商管理cal,可是每个线程保存的变量是分隔的:

public void set(T value) {
Thread currentThread = Thread.currentThread();
Values values = values(curre链表结构ntThread);
if (values == null) {
values = initializeValues(currentThread);    }
values.put(this, value);
}

上面的set办法中,valu指针万用表的读法es办法回来当时线程的localV公积金alues成员变量:

/**
* Gets Values instance for this thread an指针的拼音d variable type.
*/
Values链表的创立 values(Thread current) {
return current.localValue工商银行s;
}

那么线程内部的localValues是什么jsonp

public class Thread implements Runnable {
/**
* Normal t指针万用表的使用办法hread local values.
*/
ThreadLocal.Values localValues;
/*省掉若干代码*/
}

能够看到,Thread中的localValues是界说在ThreadLocal中线程本地的变量。假设在 values ()办法取得null值,就实施initializeValu指针数组和数组指针的差异es办法。
initia音讯机制怎样调用lizeValues是怎样完毕的呢链表回转

Values initializeValues(Thread current) {
return current.localValues = new Values();
}

然后将value的值放在当时线程的的localValues里。这样,尽管看起工程造价来访问的是用一个ThreadLocal,可是得到的值却是依据线程而不同的。

注:不同sdk中ThreadLocal内部的完毕时不相同的,比方在6.0的版别完毕的办法就不是上面的办法,可是原理仍是相同的

举个比方

public class JsonTestMetaData {
public String j指针数组和数组指针的差异son_str;
}
public class MainActivity工程造价 extends Activity {
ThreadLocal<J指针万用表的读法sonTestMet枸杞aD指针式万用表怎样读数ata> local = new ThreadLocajson字符串l<>();
@Override
projson格局tected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstan链表与数组的存储结构有什么不同ceState);
Log.d(TAG, "onCreate");
JsonTestMetaData data = new JsonTestMetaData();
data.json_str = "maijson字符串n_thread";
local.set(指针万用表的使用办法data);
Log.e(TAG, local.get().json_str)json格局;
new Thread(new Runnable() {
@Override
public void run() {
JsonTestMetaData data = new JsonTestMetaData();
data.json_str = "other_thread";
local.set(data);
Log.e(TAG, local.get().json_str);
}
}).start();
new Thread(new Runnable() {
@Ovjsonperride
pub链表是选用链式存储结构的线性表lic void run() {
if (local.get() != null) {
Log.json解析e(TAG, local.get().j链表的创立son_str);
} else {
Log.e(TAG, "local.get() is null")链表与数组的存储结构有什么不同;
}
}
}).start();
Log.e(TAG, local.get().json_str);
}
}

得到的成果:

01-09 14:28:36.41链表0 29303-29303/com.sparkfeng指针c言语bo.app.javabcsxjson格局test E/MainActivity: main_thread
01-09 14:28:36.412 29303-29303/com.sparkfengbo.app.javabcsxtest E/指针数学MainActivijsonty: main_thread
01-09 14:28:36.412 29303-29331/com.sparkfengbo.app.javabcsxtjson解析est E/MainActivity: other_thread
01-09 14:28:36.413 29303-29332/com.s指针变量parkfengbo.app.javabcsxtest E/MainActivity: local.get() is null

TheadLocal或许会引起内存走漏,假定Thread没有退出的话。

Mes链表回转sageQueue

MessageQueue是一个音讯部队,包含指针的拼音成员变量Message mMessages;,能够了解成链表链表的创立的头部。存储的方式不是部队,而是单链表。
内部包json解析括5个native办法:

private native static指针的拼音 long nativeInit();
private native static void nativeDestroy(long ptr);
private native static void nativePollOnce(long ptr, int t音讯机制和事情机制imeoutMillis);
priv指针数组和数组指针的差异ate native static void ngoogleativeWake(音讯机制是同步机制吗long ptr);
pri音讯机制和事情机制vate native static b音讯机制是一种通信机制oolean nativeIs链表结构Idling(long ptr);

底层仍是经过na狗狗币tive代码完毕的。后面的部分有翻开。

在Java层面,主要是

  • next办法,取得下一个音讯;
  • enqu链表排序eueMessage 将音讯刺进到部队链表是选用链式存储结构的线性表中。

异步音讯和音讯屏障

在ViewRootImpl的scheduleTraversals办法发现这样一段代码

void schedule工商银行Traversals() {
if (!mTraversalSchjsoneduled) {
mTraversalSchedjson是什么意思uled = true;
mTraversalBar龚俊rier = mHandler.getLooper().指针数学getQueue().postSyncBarrier();
mChoreographer.pos音讯机制有哪些tCallback(
Choreograp指针式万用表怎样读数her.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
if (!mUnbufferedInputDispatch) {
scheduleConsumeBatchedInp音讯机制结构ut();
}
notifyRendererOfFramePending();
pokeDrawLockIfN音讯机制javaeeded();
}
}

发现运用MessageQueue添加了一个音讯屏障

MessageQueue.指针变量postSy链表与数组的存储结构有什么不同ncBarrier

代码比较简单,只是向部队中刺进一个Msg,when是Syste链表mClock.uptimeMillis(),而且这个Msg没有target

    public int postSyncBarrier() {
return postSyncBarrier(SystemClock.uptimeMillis());
}
private int postSyncBarrier(long when) {
// Enqueue a new sync barrier token.
// We don't need to wake the queue b链表不具有的特点是ecause the purpose of a barrier is to stall it.
synchronized (this) {
final int token = mNextBarrierToken++;
fjson解析inal Message msg = Message.obtain();
msg.markjsonInU链表回转se();
msg.when = when;
msg.指针万用表的使用办法arg1 = token链表不具有的特点是;
Message prev =链表不具有的特点是 null;
Message p = mMessages;
if (when != 0) {
while (p != null && p.when <= when) {
prev = p;
p = p.next;
}
}
if (prev != null) { // invariant: p == prev.next
msg.next = p;
prev.next = msg;
} else {
msg.next = p;
mMessages = msg;
}
return token;指针
}
}

音讯屏障的消费

MessageQueue的next办法,假设遇到音讯屏障,就去寻找链表后第一个异步音讯,优先处理异步音讯

Message next() {
na指针的拼音tivePollOnce(ptr, nextPollTimeoutMillis);
synchronized (this) {
Message prevMsg = null;
Message msg = mMessages;
if (msg != nul宫颈癌l && msg.target == null) {
do {
prevMsg = msg;
msg = msg.next;
} while (msg != null && !msg.isAs指针数学ynchronous());
}
if (msg != null) {
if (now < msg.when) {//异步音讯还没到处理时刻,就在等会(超时时刻)
nextPollTimeoutMi音讯机制原理llis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
} else {
//异步音讯到了处理时刻,就从链表移除,回来它。
mBlocked = false;
i音讯机制原理f (链表c言语prevMsg != null) {
prevMsg.next = msg.next;
} else {
mMessages = msg.next;
}
msg.next = null;
if (DEBUjsonG) Log.v(TAG, "Returning message: " + msg);
msg.markInUse();
retur链表与数组的存储结构有什么不同n msjson格局怎样翻开g;
}
} else {
nextPollTime指针式万用表怎样读数outMillis = -1;
}
//...
}
}

异步音讯的效果

能够指针万用表的使用办法去看一下链表与数组的存储结构有什么不同Messa指针变量ge的setAsynchronous办法的注解

在View的invalidate重绘的过指针万用表的读法程,会引入同步屏障,其实便是保证异步Message优先处理,相当于插队呗。?

Certain operations, such as view invalidation, may introduce synchronization barriers into the {@link Looper}’s message queue to prevent subsequent mesjson格局sages from being delivered指针变量 until some condGoition isjson格局 met. In the case of view invalidation, messages which arejsonp跨域原理 post指针式万用表图片ed after a call to {@link android.view.View#invalid音讯机制原理ate} are suspejson字符串nded by me链表c言语ans of a synchronization barrier until the next frame is ready to be指针式万用表怎样读数 drawn. The synchroni指针万用表的读法zation barrier ensures that the inva链表结构lidation request is completely handled before resuming.

Asynchronous messages are exempt from synchronization barrier链表s. They typically repr指针变量esent interrupts, input events, and other signals that m音讯机制mqust be handle音讯机制mqd independently工程造价 even while other work h音讯机制和事情机制as been suspended.

Looper

L音讯机制结构ooper是做什json么的?Looper的职能是为一个线程创立MessageQueue,绑定到这个线程,为此线程实施音讯循环。

Looper内部包含MessageQueue和Thread的引指针式万用表

MessageQ音讯机制结构ueue在preparejson数据办法中创立,在loop办法初步循环。

Java层的Looper和MessageQueue有在C++对应的类,别离是Looper(Native)和NativeMessageQueue类

线程默许是没有looper的指针万用表的使用办法,除非你在线程调用prep音讯机制怎样调用are办法,然后链表结构才华实施loop办法才华进行音讯处理。

prepare做了什么呢?

private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created pe链表排序r链表不具有的特点是 thre链表是选用链式存储结构的线性表ad");
}
sThreadLocal.set(new Looper(quitAllowed));}

你能够看到prepa链表有哪三种方式re()办法只能调用一次。在最后会创立一个Looper放在ThrGoeadLocal里保存。
Looper是怎样创立的呢指针变量

private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Threa音讯机制是一种通信机制d.currentThread();
}

能够看到,结构办法是私有的,新创立了一个MessageQueue,mThread便是当时线程。
那么Looper是怎样实施音讯循环的?

public音讯机制原理 static void loop() {
/*中心省掉若干代码*/
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thr工商管理ead.");
}
final MessageQueue queue = me.mQueue;
for (;;) {
Message msg = queue.next();
msg.target.dispatchMessage(msg);
msg.recycleUnchecked();
}
}

能够看到,经过一个无限循环,不断的在音讯部队中拿音讯,将音讯分发到指定的当地。

Message的target其实便是Handler

所以,在你写的线程中,能够这样运用:

class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = newjson文件是干什么的 Handlerjsonp() {
public void handleMessage(Message msg) {
// process incominjson解析g messages here
}
};
Looper.loop();
}
}

不过上音讯机制结构述的办法太low,在代码中也不方便,能够这样写:

HandlerThread

HandlerThread thread  = new HandlerThread("new_handler_thread");
Handler handler = new Handler(thread.getLoope音讯机制结构r(), new Handler.Callba音讯机制结构ck() {
@Override
public boolean handleMessage(Message msg) {
return false;
}
});

HandlerThread承继自Thread,自身会创立一个Looper。

关于 HandlerThread可参看 Androjsonpid HandlerTh链表是选用链式存储结构的线性表read 完全解析

大多数和音讯循环的交互都是经过Handler去完毕的,就像你在Handler那部分看到的那样。记住在你不再实施音讯循环的时分调用Looperquit办法。

Handler

Handler能够发送和处理和MessageQ指针的拼音ueue相关的 MessageRunnable。每个Handler和一个独自的线程相关,这个线程便是你创立这个Handler的时分地址的线程,需求处理的MessageQueue也是这个线程的MessageQueue

请看:

public Handler(Calgooglelback callback, boolean async) {
/*省掉若干代码*/
mLooper = Loo音讯机制有哪些per.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thr链表不具有的特点是ead that has not called Looper.prepajsonpre()");}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
public Handler(Looper looper, Callback callback, boole指针的拼音an async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}

Handler有很多个结构音讯机制面试题函数,毕竟都会调用到这个结构函数。你能够看到Handler中的的Looper成员,便是经过Looper的静态链表有哪三种方式办法myLooper指针得到的,myLooper是干啥的?你能够看Looper的内容,在上面代码中得到了一个和这个线程相关的Looper。假设 mLooper成员是null,那么就抛出异常。你或许会问,我在activity中随意创立ha音讯机制结构ndle工商银行r啊,没有调用Looper.myLooper()办法。那是由于当你的使链表c言语用作业的时分,Android现已经过Looper的静态办法prepareMainLooper创立了,这个办法只指针式万用表能实施一次,否则就会抛出异常了。这个Looper适宜线程绑定的,你再看看mQueue,是从mLooper中拿到的。

调用的次序如下:

  • Message的callback是否是null?不是调用callback的run办法(其实这儿Messag指针万用表的使用办法e的callback是一个Runnable政策,经过Handler的post办法传递)jsonp
  • Handler的callback是否是null?不是调用callback。这儿的callbac指针万用表的读法k的类型是Handler.Callback()
  • 毕竟调用Handler的handleMessage的办法。
    /**
* Handle system messages here.
*/
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.ha音讯机制是一种通信机制ndleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}

MessageQueue.IdleHandler

  • 《你知道android的MessageQueue.IdleHandler吗?》

简而言之,便是在looper里边的message暂时处理完了,这个时分会回调这个接口,回来false,那么就会移除它,回来true就会在下次message处理完了的时分继续回调

Native的完毕

这儿能够参看Gityuan – Android音讯机制2-Handler(Native层)

Handler面试必会知识点

MessageQueue

MessageQueue.java


M宫颈癌前期症状essageQueue(boolean quitAllowed) {
mQuitAllowed = quitAllowed;
mPtr = nativeInit();  //mPtr记载na音讯机制tive音讯部队的信息 【2】
}
private native static long nativeInit();
private native static void nativeDestroy(long ptr);
privat链表e native void nativePollOnce(long ptr, int timeoutMillis);
private native s链表排序tatic void n音讯机制ativeWake(long ptr);
private native static boolean nativeIsPolling宫颈癌前期症状(long ptr);
private native sta链表回转tic void nativeSetFileDescriptorEvents(long ptr, int fd, intjson events);

能够宫颈癌看到java层的mPtr实际上是native层地址指针,关于reinterpret_cast

static jlong android_os_MessageQueue_nativeInijson文件是干什么的t(JNIEnv* env, jclass clazz) {
//初始化native音讯部队 【3】
NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue();
nativeMessageQueue->incStron指针式万用表图片g(env); //添加引证计数
return reinterpret_cast<jlon指针式万用表怎样读数g>(nativeMessag指针万用表的使用办法eQueue);
}

和Java指针变量不相同的是,nat链表ive的Message音讯机制Queue内部有一个looper

NativeMessageQueue::NativeMessageQueue()
: mPollEnv指针数学(NULL), mPollOJSONbj(NULL), mExcejson解析ptionObj(NULL) {
mLooper = Looper:jsonp:getForThread(); //获取TLS中的Looper政策
if (mLooper == NULL) {
mLooper = new L指针式万用表ooper(false); //创立native层的Looper 【4】
Looper::setForThread(mLooper); //保存native层的Looper到TL公积金S
}
}
  • nativeInit()办法:
    • 创立了Nativ工程造价eMessagjson格局怎样翻开eQueue政策,添加其引证计数,并将NativeMessageQueue指针mPtr保存在Java层的MessageQueue
    • 创立了Native Looper政策
    • 调用epoll的epoll_create()/epoll_ctl()来完毕对mWakeEventFd和mRequests的可读作业监听
  • nativeDestroy()办法
    • 调用RefBase::decStrong()来削减政策的json格局怎样翻开引证计数
    • 当引证计json解析数为0时,则删去NativeMessageQueue政策
  • nativePollOnce()办法
    • 调用Looper::pollOnce音讯机制是同步机制吗()来完毕,json数据空闲时停留在epoll_wait()办法,用于等候作业发生或许超时
  • nativeWake()办法
    • 调用Looper::wake()来完毕,向管道mWjson字符串akeEventfd写入字符;

Looper#创立epoll作业

Loop链表排序er::Ljson数据ogoogleoper(bool allowNonCallbacks) :音讯机制面试题
mAllowNonCallbacks(allowNo指针式万用表图片nCallbacks), mSendingMessage(false),
mPolling(false), mEpollFd(-1), mEpollRebuildRequired(false),
mNextRequestSeq(0), mResponseIndex(0), mNextMessageUptime(LLONG_MAX) {
mWakeEventFd = event链表排序fd(0, EFD_NONBLOCK); //结构唤醒作业的fd
AutoMutex _l(mLock);
rebuildEpollLocked();  //重建Epoll作业【5工程造价】
}

eventfd

void Looper::rebuildEpoll工程造价Locked() {
if (mEpollFd >指针c言语= 0) {
close(m链表不具有的特点是EpollFd); //关闭旧的epoll实例
}
mEpollFd = epoll_create(EPOLL_SIZE_HINT);工商管理 //创立新的epoll实例,并注册wake管道
struct epoll_event eventItem;
memset(& eventItem, 0, sizeof(epoll_event)); //把未运用的数据区域进行置链表排序0操作
eventItem.events = EPOLLIN; //可读作业
eventItem.data.fd = mWakeE指针式万用表怎样读数ventFd;
//将唤指针c言语醒作业(mWakeEventFd)添加到epoll实例(mEpollFd)
int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeEvejson数据nt龚俊Fd, & evenjsonp跨域原理tItem);
for (size_t i = 0; i < mRequejson解析sts.size(); i++) {
const Reque指针式万用表st& request = mR链表回转equests.valueAt(链表结构i);
struct epoll_event eventItem;
request.initEve链表c言语ntItem(&eventItem);
//将request部队的作业,别离添加到epoll实例
int epollRes宫颈癌前期症状ult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, request.fd, & eventItem);google
}
}

epoll

Gityuan – select/poll/epoll对比剖析指针c言语

监督的描述符数量不受捆绑,所支撑的FD上限是最大能够翻开文件的数目,具体数目能够cat /proc/sys/fs/file-max枸杞检查,一般来说这个数目和体系内存关系很大,以3G的手机来说这个值为20-30万。

IO功能不会跟着监督fd的数量添加而下降。epoll不同于select和poll轮询的办法,而是经过每个fd界说的狗狗币回调函数来完毕的,只指针万用表的读法需安排稳当的fd才会实施回调函数。

nativePollO链表结构nce音讯机制面试题

Message next() {
final long ptr指针式万用表图片 = mPtr;
if (ptr == 0)音讯机制java {
return null;
}
for (;;) {
...
nativePol音讯机制是同步机制吗lOnce(ptr, n链表与数组的存储结构有什么不同extPollTimeoutMillis); //堵塞操作 【2】
...
}

android_os_MessageQueue.cpp

static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj, jlong ptr, jint timeoutMillis) {
//将Java层传递下来的mPtr转换指针数组和数组指针的差异为nativeMessageQueue
NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>链表排序(ptr);
nativeMessageQueujson格局怎样翻开e->po狗狗币llOnce(env, obj, time指针式万用表outMillis); 【3】
}

and工商银行roid_os_MessageQueJSONue.音讯机制和事情机制cpp

void NativeMessageQueue::pollOnce(JNIEnv* env, jobject pollObj, int timeoutMillis) {
mPollEnv = env;
mPollObj = pollObj;
mLoop音讯机制er->pollOnce(timeoutMillis); 【4】
mPollO链表的创立bj = NULL;
mPollEnv = NULL;
if (mExcjson是什么意思eptionObj) {枸杞
env->Throwjsonp(mExceptionObj);枸杞
env->DeleteLocalRef(mExceptionObj);
mExceptionObj音讯机制是同步机制吗 = NULL;
}
}

Looper.h

inline int pollOnce(int timeoutMillis) {
return pollOnce(timeoutMillis, NULL, NULL, NULL); 【5】
}

Looper.c链表的创立pp

int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
int result = 0;
f宫颈癌or (;;) {
// 先处理没有Callback办法的 Response作业
while (mRe音讯机制是一种通信机制spons指针式万用表怎样读数eIndex < mResponses.size()) {
const Response& response = mRespo指针万用表的读法nses.ijson字符串temAt(mResponseIndex++);
int ident = response.requ音讯机制面试题est.ident;
if (ident &gt指针;= 0) { //ident大链表排序于0,则表明没有callback, 由于POLL_CALLBACK = -2,
int fd = response.request.fd;
in音讯机制结构t events = response.events;
void* data = response.request.dat指针变量a;
if (outFd != NULL) *指针式万用表outFd = fd;
if (outEvents != N指针ULL) *outEvents = events;
if (outData != NULL) *outData = data;
return idejsonpnt;
}
}
if (链表回转result != 0) {
if (outFd != NULL) *outFd = 0;
if (outEvents != NULL) *outEvents = 0;
if (outData != NULL) *outData = NULL;龚俊
return result;
}
// 再处理内部轮询狗狗币
result = pollInner(timeoujson文件是干什么的tMillis); 【6】
}
}

nativeWake

调用Looper::wake()来完毕,向管道mWakeEventfd写入音讯机制java字符;(epoll的唤醒作业)

boolean enqueueMessage(Message msg, long when) {
... //将Message按时刻次序刺进MessageQueue
if (needWake) {
nativeWak宫颈癌前期症状e(mPtr); 【2】
}
}
static void android_os_Me指针式万用表ssageQueu宫颈癌前期症状e_nativeWake(JNIEnv* env, jclass claz宫颈癌z, jlojson格局ng ptr) {
NativeMessageQueue* na指针式万用表怎样读数tiveMessageQueuejson = reinterpret_cast<NativeMessageQueue*>(ptr);
nativeMessageQueue->wake(); 【3】
}
void NativeMessageQu指针c言语eue::wake() {
mLooper->wake();  【4】
}
void Looper::wake() {
uint64_t inc = 1;
// 向管道mWakeEventFd写入字符1
ssize_t nWrite = TEMP_FAILURE_RETRY(write(json解析mWakeEventFd, &inc, sizeof(uint64_t)));
if (nWrite != sizeof(uint64_t)) {
if (e公积金r音讯机制mqrno != EAGAIN) {
ALOGW(json"Could not write音讯机制原理 wake signal枸杞, errno=%d", errno);
}
}
}

postDelay的json是什么意思完毕

  • 1.调用sendMessageAt音讯机制是同步机制吗Time,核算当时时刻和delay时刻,调用MessageQueue的enqueMessage入队
  • 2.MessageQueue的enqueueMessa龚俊ge会遍历部队,依据Message的when核算刺进到部队的方位,假设next的死循环处于堵塞,就会调用native办法唤醒NativeMessageQueue
  • 3.nativePollOnce会将时刻传递给Looper.cpp的办法,实际上是epoll_wait(mEpojsonpllFd, eventI链表和数组的差异tems, EPOLLGo_MAX_EVEN指针万用表的使用办法TS, timeoutMillis); 也便是epoll的堵塞时刻。
public final boolean postDelayed(Runnable r, long delayMillis)
{
return sendMessajson字符串geDelayed(getPostMessa音讯机制mqge(r), delayMillis);
}
public final boolean sendMessageDelayjson解析ed(M音讯机制是同步机制吗es链表回转sage msg, long delayMillis音讯机制java)
{
if (delayM链表有哪三种方式illis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMi音讯机制llis() + delayMillis);指针式万用表怎样读数
}
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
Run指针式万用表timeException e = new RuntimeException(
this + " sendMessajson是什么意思geAtTime() called with no mQueue");
Log.w("Looper", e.getMessa链表ge(), e);
return f指针数组和数组指针的差异alse;
}
return enqueueMessage(queu链表e, msg, uptimeMillis);
}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillgoogleis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchr工商银行onous(trjson文件是干什么的ue);
}
return queue.enqueu链表是选用链式存储结构的线性表eMessage(msg, uptimeMillis);
}
 boolean enqueueMessage(Message msg, long when) {
if (msg.tar链表结构gjson格局怎样翻开et == null) {
throw new IllegalArgumentException("Message must have a target.");
}
if (msg.isInUse()) {
throw new IllegalStateException(msg + " This message is a链表排序lready in use.json数据");
}
synch链表是选用链式存储结构的线性表ronized (this) {
if (mQuitting) {
IllegalStateException e = new IllegalStateException(
msg.target + "链表不具有的特点是 sending message to a Handle音讯机制怎样调用r on a dead thread");
Log.w(TAG, e.getMessage(), e);
msg.recyc指针式万用表le();
return false;
}
msg.markInUse();
msg.when = when狗狗币;
Message p = mMess链表和数组的差异ages;
bo枸杞olean needWake;
if (p == null || when == 0 || when &音讯机制和事情机制lt; p.when) {
// New head, wake up the event queue if blocked.
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
// Inserted within the公积金 mi指针数组和数组指针的差异ddle of the queue.  Usually we don't音讯机制原理 have to wake
// up the event queue unle链表有哪三种方式ss there is a barrier at the head of the queue
// and th指针e message is the earlies音讯机制面试题t asynchronous message in the queue.
needWa指针的拼音ke = mBlocked && p.targejson格局t == null && msg.isAsynchronous();
Message prev;
for (;;) {
prev = p;
p = p.next;
if (p == null || when < p.when) {
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
// We can assume mPtr != 0 because mQuitting is false.
if (needWake指针数组和数组指针的差异) {
nativeWake(mPtr);
}
}
return true;
}

HandlerThread

承继自Thread,r指针数学un的时分会调用Looper.prepare();有两个比较重要的办法

public Looper getLo链表结构oper()

public Handler getThreadHandler()

运用完毕后需求调用quit()

IntentService

onCreate()会创立HandlerThread狗狗币并star链表和数组的差异t,创立刚才的HandlerThread的Looper的S工商管理erviceHandler
Overide的onHandleIntent办法是在异步线程中实施指针万用表的使用办法

参看和问链表c言语

  • [Android中为什么主线链表结构程不会由于Looper.loop()里的死循环卡死?

](www.zhihu.com/question/34…)jsonp跨域原理

  • 我自己好久之前写的一些笔记

  • Gityuan – Android音讯机制1-Handler(Java层)

  • Gityjson格局uan – Android音讯机制2-Handler(Native层)

  • Gityuan – seJSONlect/poll/epoll对比剖析

  • Gityuan – 源码解读epoll内核机制