AlbumSetPage
AlbumSetPage的幾個重要成員,如圖:
AlbumSetPage刷新AlbumSet,每個看到的相集都是SlotView。而SlotView主要由TiledTexture和label組成。如圖:
簡單的說,SlotView的繪製過程爲:SlotView::render(…) -> renderItem() -> AlbumSetSlotRender::renderSlot() -> renderContent(…) 、renderLabel(…)、renderOverlay(…)。流程圖如下:
下面詳細說明下SlotView的刷新流程,先看代碼流程圖,後面附加流程說明:
1) AlbumSetPage的onResume()中,mAlbumSetView.resume()。它會調用mDataWindow.resume()。mDataWindow是AlbumSetSlidingWindow類型。代碼如下:
public void resume() {
mIsActive = true;
TiledTexture.prepareResources();
for (int i = mContentStart, n = mContentEnd; i < n; ++i) {
prepareSlotContent(i);
}
updateAllImageRequests();
}
在for循環中調用prepareSlotContent(i)逐個更新相集顯示內容並往mData中記錄AlbumSetEntry數據。代碼如下: private void prepareSlotContent(int slotIndex) {
AlbumSetEntry entry = new AlbumSetEntry();
updateAlbumSetEntry(entry, slotIndex);
mData[slotIndex % mData.length] = entry;
}
2) 在updateAlbumSetEntry中會獲取到相集的title、album、cover、labelLoader以及coverLoader。 private void updateAlbumSetEntry(AlbumSetEntry entry, int slotIndex) {
MediaSet album = mSource.getMediaSet(slotIndex);
MediaItem cover = mSource.getCoverItem(slotIndex);
int totalCount = mSource.getTotalCount(slotIndex);
entry.album = album;
……
entry.setPath = (album == null) ? null : album.getPath();
String title = (album == null) ? "" : Utils.ensureNotNull(album.getName());
int sourceType = DataSourceType.identifySourceType(album);
if (isLabelChanged(entry, title, totalCount, sourceType)) {
entry.title = title;
entry.totalCount = totalCount;
……
if (album != null) {
entry.labelLoader = new AlbumLabelLoader(
slotIndex, title, totalCount, sourceType);
}
}
entry.coverItem = cover;
if (getDataVersion(cover) != entry.coverDataVersion) {
……
if (cover != null) {
entry.coverLoader = new AlbumCoverLoader(slotIndex, cover);
}
}
}
3) 回頭再看第一步中調用的updateAllImageRequests(),代碼如下: private void updateAllImageRequests() {
mActiveRequestCount = 0;
for (int i = mActiveStart, n = mActiveEnd; i < n; ++i) {
AlbumSetEntry entry = mData[i % mData.length];
if (startLoadBitmap(entry.coverLoader)) ++mActiveRequestCount;
if (startLoadBitmap(entry.labelLoader)) ++mActiveRequestCount;
}
……
}
在for循環中將逐個加載cover、label。startLoadBitmap(entry.coverLoader和startLoadBitmap(entry.labbelLoader從參數類型BitmapLoader看,調用startLoader()會執行各個loader的submitBitmapTask()。詳細代碼如下:AlbumSetSlidingWindow.java
private static boolean startLoadBitmap(BitmapLoader loader) {
if (loader == null) return false;
loader.startLoad();
return loader.isRequestInProgress();
}
BitmapLoader.java
public synchronized void startLoad() {
if (mState == STATE_INIT) {
mState = STATE_REQUESTED;
if (mTask == null) mTask = submitBitmapTask(this);
}
}
這個在前面介紹ThreadPool的時候提到過,submit之後會在線程池中執行任務加載圖片,從線程池的代碼run()中知道完成圖片回去後,會調用Listener.onFeatureDone,從future.get中得到Bitmap傳給mLoadComplete(mBitmap)。 發送消息MSG_UPDATE_ALBUM_ENTRY調用Loader的updateEntry()。mRootPane的onLayout調用過程詳解:
這個調用過程和Activity的啓動流程有關。mRootPane作爲一個GLView, 在onResume()時調用setContentPane(mRootPane)設置。在Activity的啓動流程中,ActivityThread會調用handleResumeActivity中,先執行performResumeActivity, 後執行wm.addView()。最終會調用到ViewRootImpl的requestLayout() –>View.dispatchAttachedToWindow -> onAttachedToWindow -> GLSurfaceView.onAttachedToWindow -> GLThread.start() -> GLThread.guardedRun() -> onSurfaceCreated()、onSurfaceChanged()、 onDrawFrame() -> onDrawFrameLocked() -> layoutContentPane() -> mContentView.layout()。
其中mContentView即在onResume中SetContentPane()傳入的參數mRootPane。
歡迎轉載和技術交流,轉載請幫忙註明出處,http://blog.csdn.net/discovery_by_joseph,謝謝!