android의 메시지 공유 변수 풀 구현

2888 단어
전언
Message를 사용할 때 어떻게 복용 메커니즘을 실현하는지, 그리고 자신이 유사한 것을 실현할 수 있는지에 관심이 많아서 몇 분 동안 생각을 정리하고 잊어버리지 않도록 참고할 수 있습니다.
데이터 형식
    /*package*/ 
    Message next;//       
    private static final Object sPoolSync = new Object(); //   
    private static Message sPool;//     

회수 논리
  /**
     * Return a Message instance to the global pool.
     * 

* You MUST NOT touch the Message after calling this function because it has * effectively been freed. It is an error to recycle a message that is currently * enqueued or that is in the process of being delivered to a Handler. *

*/ public void recycle() { if (isInUse()) { if (gCheckRecycle) { throw new IllegalStateException("This message cannot be recycled because it " + "is still in use."); } return; } recycleUnchecked(); } /** * Recycles a Message that may be in-use. * Used internally by the MessageQueue and Looper when disposing of queued Messages. */ void recycleUnchecked() { // Mark the message as in use while it remains in the recycled object pool. // Clear out all other details. flags = FLAG_IN_USE; what = 0; arg1 = 0; arg2 = 0; obj = null; replyTo = null; sendingUid = -1; when = 0; target = null; callback = null; data = null; synchronized (sPoolSync) { if (sPoolSize < MAX_POOL_SIZE) { next = sPool; sPool = this; sPoolSize++; } } }

재사용 논리

    /**
     * Return a new Message instance from the global pool. Allows us to
     * avoid allocating new objects in many cases.
     */
    public static Message obtain() {
        synchronized (sPoolSync) {
            if (sPool != null) {
                Message m = sPool;
                sPool = m.next;
                m.next = null;
                m.flags = 0; // clear in-use flag
                sPoolSize--;
                return m;
            }
        }
        return new Message();
    }


잊어버리다
sPool은 메시지 유형 데이터를 가리키는 인용(현 단계는 공유 탱크로 볼 수 있음)이고,next도 메시지 대상 인용으로 위조된 체인 테이블의 한 끝이라고 볼 수 있다.recycle에서 이 메시지 대상을 공유 탱크에 저장합니다.obtain에서는 공유 풀에서 메시지 대상을 가져옵니다.
첫 번째 메시지 대상이 Recycle일 때, sPool에 자신의 값을 부여하고,next가null을 가리킨다.이 때 두 번째 회수:next는 첫 번째recycle에서 회수된 대상의 인용을 가져와 자신이 (sPool) 변수 탱크가 되는 것을 가리킨다.이런 식으로 미루어 하나하나 창고에 넣다.
obtain의 첫 번째 메시지 대상은 sPool=null이기 때문에 첫 번째 대상은 new에서 나온 것이다.obtain이 두 번째로 집행할 때, sPool!=null, 이 때 sPool을 가져오면 sPool의 다음 대상을 sPool로 하고 m.next를 비워 창고에서 팝업합니다.
사고 방향의 총결산.
창고를 위조하는 생각은 확실히 괜찮다.우리는 회수할 때 사용한 메시지 대상을 맨 위에 놓고 사용할 때도 맨 위에서 얻는다.고정된 창고의 크기를 유지하다.

좋은 웹페이지 즐겨찾기