展会信息港展会大全

Android 中的 MessageHandler 机制
来源:互联网   发布日期:2016-01-13 22:06:51   浏览:4917次  

导读:总体思想就是两个(多个)线程共享一块存储区域,它们并发地操作这块内存。下面是我自己初步写的模拟程序。这里仅贴上Hander, HandlerThread, Looper201packagecom.zte.liu;0203publicclassHandler {0405priv......

总体思想就是两个(多个)线程共享一块存储区域,它们并发地操作这块内存。

下面是我自己初步写的模拟程序。

这里仅贴上Hander, HandlerThread, Looper2

01

package com.zte.liu;

02

03

public class Handler {

04

05

private Looper2 looper = null;

06

07

public Handler(Looper2 looper){

08

this.looper = looper;

09

}

10

11

public Message obtainMessage(){

12

return new Message(this);

13

}

14

15

public Message obtainMessage(int id){

16

return new Message(id, this);

17

}

18

19

public void dispatchMsg(Message msg){

20

handleMessage(msg);

21

}

22

23

public Looper2 getLooper(){

24

return looper;

25

}

26

27

public void handleMessage(Message msg){//钩子函数

28

System.out.println(msg.getId());

29

}

30

}

1

public class HandlerThread implements Runnable{

2

public void run(){

3

Looper2.prepare();

4

Looper2.loop();

5

}

6

}

01

package com.zte.liu;

02

03

public class Looper2 {

04

05

private static Looper2 looper = null;

06

private MessageQueue<Message> mQueue;

07

08

private Looper2(){

09

mQueue = new MessageQueue();

10

}

11

12

public static void prepare(){

13

if(looper == null){

14

looper = new Looper2();

15

}

16

}

17

18

public static Looper2 myLooper(){

19

prepare();

20

return looper;

21

}

22

23

public MessageQueue<Message> getQueue(){

24

return mQueue;

25

}

26

27

public static final void loop(){

28

System.out.println("loop begin...");

29

Looper2 looper = myLooper();

30

MessageQueue<Message> queue = looper.mQueue;

31

if(looper == null) {

32

return;

33

}

34

while(true){

35

System.out.println("----queue size ="+queue.size());

36

try {

37

Thread.sleep(1000);

38

} catch (InterruptedException e) {

39

e.printStackTrace();

40

}

41

Message msg = (Message)queue.next();

42

if(msg != null){

43

if(msg.getHandler() == null)return;

44

else{

45

msg.getHandler().dispatchMsg(msg);

46

Message.recycle(msg);

47

}

48

}

49

}

50

}

51

}

既然是这个机制是多线程操作的,就要多用用线程的概念。

准备知识:

1. obj.notify() 与 obj.wait()

分别表示:

释放等待队列中等待在obj对象上的线程;

当前线程因需要等待obj对象而进入等待队列

2. ThreadLocal类,知道其get()与set(obj)方法的含义。

参考源码jdk1.5:

总体思路:

每个线程都有一个ThreadLocalMap。

当调用ThreadLocal.set(value)时,取出当前线程的ThreadLocalMap,然后map.set(ThreadLocal对象,value);

当调用ThreadLocal.get()时,取出当前线程的ThreadLocalMap,然后return map.get(ThreadLocal对象);

源码:

01

public class ThreadLocal<T> {

02

03

private final int threadLocalHashCode = nextHashCode();

04

05

private static int nextHashCode = 0;

06

private static final int HASH_INCREMENT = 0x61c88647;

07

08

private static synchronized int nextHashCode() {

09

int h = nextHashCode;

10

nextHashCode = h + HASH_INCREMENT;

11

return h;

12

}

13

14

15

public ThreadLocal() {

16

}

17

18

19

public T get() {

20

Thread t = Thread.currentThread();

21

ThreadLocalMap map = getMap(t);

22

if (map != null)

23

return (T)map.get(this);

24

25

// Maps are constructed lazily. if the map for this thread

26

// doesn't exist, create it, with this ThreadLocal and its

27

// initial value as its only entry.

28

T value = initialValue();

29

createMap(t, value);

30

return value;

31

}

32

33

34

public void set(T value) {

35

Thread t = Thread.currentThread();

36

ThreadLocalMap map = getMap(t);

37

if (map != null)

38

map.set(this, value);

39

else

40

createMap(t, value);

41

}

42

43

44

ThreadLocalMap getMap(Thread t) {

45

return t.threadLocals;

46

}

47

48

49

void createMap(Thread t, T firstValue) {

50

t.threadLocals = new ThreadLocalMap(this, firstValue);

51

}

52

53

.......

54

55

56

static class ThreadLocalMap {

57

58

........

59

60

}

61

62

}

最后看看改进的ThreadHandler和Looper类

01

package com.zte.liu;

02

03

public class HandlerThread extends Thread{

04

05

private Looper mLooper;

06

07

public void run(){

08

Looper.prepare();

09

synchronized(this){//本身线程会对mLooper存储区域做写操作,故需要放置临界区

10

mLooper = Looper.myLooper();

11

this.notifyAll();//通知等待在this对象上的线程走出等待队列

12

}

13

Looper.loop();

14

}

15

16

public Looper getLooper(){//其他线程会对mLooper存储区域做读操作,故需要放置临界区

17

if(!isAlive()){

18

return null;

19

}

20

//if the thread has been started, wait until the looper has been created.

21

synchronized(this){

22

while(isAlive() && mLooper==null){

23

try {

24

this.wait();//当前线程因等待this对象而进入等待队列

25

} catch (InterruptedException e) {

26

e.printStackTrace();

27

}

28

}

29

}

30

return mLooper;

31

}

32

33

}

01

package com.zte.liu;

02

03

import com.zte.liu.*;

04

05

public class Looper{

06

07

private static final ThreadLocal sThreadLocal = new ThreadLocal();

08

private MessageQueue<Message> mQueue;

09

10

private Looper(){

11

mQueue = new MessageQueue<Message>();

12

}

13

public synchronized static final void prepare(){

14

if(sThreadLocal.get() != null){

15

throw new RuntimeException("sThreadLocal already contains looper object");

16

}

17

sThreadLocal.set(new Looper());

18

}

19

20

public static final void loop(){

21

System.out.println("loop begin...");

22

Looper looper = myLooper();

23

MessageQueue<Message> queue = looper.mQueue;

24

if(looper == null) {

25

return;

26

}

27

while(true){

28

System.out.println("----queue size ="+queue.size());

29

try {

30

Thread.sleep(1000);

31

} catch (InterruptedException e) {

32

e.printStackTrace();

33

}

34

Message msg = (Message)queue.next();

35

if(msg != null){

36

if(msg.getHandler() == null)return;

37

else{

38

msg.getHandler().dispatchMsg(msg);

39

Message.recycle(msg);

40

}

41

}

42

}

43

}

44

public static Looper myLooper(){

45

return (Looper)(sThreadLocal.get());

46

}

47

public MessageQueue<Message> getQueue(){

48

return mQueue;

49

}

50

51

}

赞助本站

人工智能实验室

相关热词: MessageHandler

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港