Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android短彩信幻燈片異步加載機制

android短彩信幻燈片異步加載機制

編輯:關於Android編程

記不清是android 4.0之後還是4.1之後,浏覽信息時,彩信幻燈片不再隨著信息內容一並顯示,而是在信息內容顯示後,開啟後台線程,異步加載彩信幻燈片,加載完畢之後再顯示附件。為什麼要這麼設計那?主要是為了解決彩信顯示緩慢的問題。在原先的設計中,彩信想要顯示,首先要做准備工作,准備工作包括從數據庫中加載信息的內容,收件人,發送時間,主題,類型,狀態報告等基礎內容,其中還包括了一項費時的操作,那就是加載彩信幻燈片附件。只有上述工作全部完成之後彩信才會顯示在界面上,用戶才可以進行浏覽。這種設計非常容易卡機,有時還會引起ANR(應用程序無相應),尤其當我們的運營商要求彩信幻燈片支持20頁(默認10頁),這個問題就更加嚴重,長時間不顯示信息,嚴重影響性能。其實從功能設計上來說,用戶首先希望看到的是彩信收件人,彩信主題,發送時間,發送狀態報告等基礎信息,然後才會選擇查看幻燈片等多媒體附件。我們完全可以將幻燈片的加載滯後。androd目前給出了這樣的一個設計。 首先根據當前回話,查詢數據庫,加載信息條目。每一個信息條目,每一條信息條目,用視圖MessageListItem來顯示,信息內容數據包裝在MessageItem中。 MessageListAdapter.java [java]  public View newView(Context context, Cursor cursor, ViewGroup parent) {           int boxType = getItemViewType(cursor);           View view = mInflater.inflate((boxType == INCOMING_ITEM_TYPE_SMS ||                   boxType == INCOMING_ITEM_TYPE_MMS) ?                           R.layout.message_list_item_recv : R.layout.message_list_item_send,                           parent, false);           if (boxType == INCOMING_ITEM_TYPE_MMS || boxType == OUTGOING_ITEM_TYPE_MMS) {               // We've got an mms item, pre-inflate the mms portion of the view               view.findViewById(R.id.mms_layout_view_stub).setVisibility(View.VISIBLE);           }           return view;       }     這個view就是MessageLIstItem。然後MessagelistAdapter會調用bindView方法,完成視圖的加載,在加載中,主要是調用MessageItem的bind方法。我們現在主要關心的是MessageItem對彩信內容數據的加載,以及著重注意異步加載幻燈片附件的邏輯處理。 [java]   @Override      public void bindView(View view, Context context, Cursor cursor) {          if (<strong>view instanceof MessageListItem</strong>) {              String type = cursor.getString(mColumnsMap.mColumnMsgType);              long msgId = cursor.getLong(mColumnsMap.mColumnMsgId);                 <strong>MessageItem msgItem = getCachedMessageItem(type, msgId, cursor);</strong>              if (msgItem != null) {                  MessageListItem mli = (MessageListItem) view;                  int position = cursor.getPosition();                  mli.bind(msgItem, position == cursor.getCount() - 1, position);                  mli.setMsgListItemHandler(mMsgListItemHandler);              }          }      }     根據信息的type以及msgId,通過getCachedMessageItem方法,得到一個MessageItem。 [java]   public MessageItem getCachedMessageItem(String type, long msgId, Cursor c) {           MessageItem item = mMessageItemCache.get(getKey(type, msgId));           if (item == null && c != null && isCursorValid(c)) {               try {                   <strong>item = new MessageItem(mContext, type, c, mColumnsMap, mHighlight, mFullTimestamp, mSentTimestamp);</strong>                   mMessageItemCache.put(getKey(item.mType, item.mMsgId), item);               } catch (MmsException e) {                   Log.e(TAG, "getCachedMessageItem: ", e);               }           }           return item;       }   在MessageItem中會對cursor中的數據進行加載。 MessgeItem.java [java]  MessageItem(Context context, String type, final Cursor cursor,               final ColumnsMap columnsMap, Pattern highlight, boolean fullTimestamp, boolean sentTimestamp) throws MmsException {           mContext = context;           mMsgId = cursor.getLong(columnsMap.mColumnMsgId);           mHighlight = highlight;           mType = type;           mCursor = cursor;           mColumnsMap = columnsMap;           mFullTimestamp = fullTimestamp;           mSentTimestamp = sentTimestamp;              if ("sms".equals(type)) {               mReadReport = false; // No read reports in sms                  long status = cursor.getLong(columnsMap.mColumnSmsStatus);               if (status == Sms.STATUS_NONE) {                   // No delivery report requested                   mDeliveryStatus = DeliveryStatus.NONE;               } else if (status >= Sms.STATUS_FAILED) {                   // Failure                   mDeliveryStatus = DeliveryStatus.FAILED;               } else if (status >= Sms.STATUS_PENDING) {                   // Pending                   mDeliveryStatus = DeliveryStatus.PENDING;               } else {                   // Success                   mDeliveryStatus = DeliveryStatus.RECEIVED;               }                  mMessageUri = ContentUris.withAppendedId(Sms.CONTENT_URI, mMsgId);               // Set contact and message body               mBoxId = cursor.getInt(columnsMap.mColumnSmsType);               mAddress = cursor.getString(columnsMap.mColumnSmsAddress);               if (Sms.isOutgoingFolder(mBoxId)) {                   String meString = context.getString(                           R.string.messagelist_sender_self);                      mContact = meString;               } else {                   // For incoming messages, the ADDRESS field contains the sender.                   mContact = Contact.get(mAddress, false).getName();               }               mBody = cursor.getString(columnsMap.mColumnSmsBody);                  // Unless the message is currently in the progress of being sent, it gets a time stamp.               if (!isOutgoingMessage()) {                   // Set "received" or "sent" time stamp                   long date = cursor.getLong(columnsMap.mColumnSmsDate);                   if (mSentTimestamp && (mBoxId == Sms.MESSAGE_TYPE_INBOX)) {                       date = cursor.getLong(columnsMap.mColumnSmsDateSent);                   }                   mTimestamp = MessageUtils.formatTimeStampString(context, date, mFullTimestamp);               }                  mLocked = cursor.getInt(columnsMap.mColumnSmsLocked) != 0;               mErrorCode = cursor.getInt(columnsMap.mColumnSmsErrorCode);           } else if ("mms".equals(type)) {               mMessageUri = ContentUris.withAppendedId(Mms.CONTENT_URI, mMsgId);               mBoxId = cursor.getInt(columnsMap.mColumnMmsMessageBox);               mMessageType = cursor.getInt(columnsMap.mColumnMmsMessageType);               mErrorType = cursor.getInt(columnsMap.mColumnMmsErrorType);               String subject = cursor.getString(columnsMap.mColumnMmsSubject);               if (!TextUtils.isEmpty(subject)) {                   EncodedStringValue v = new EncodedStringValue(                           cursor.getInt(columnsMap.mColumnMmsSubjectCharset),                           PduPersister.getBytes(subject));                   mSubject = v.getString();               }               mLocked = cursor.getInt(columnsMap.mColumnMmsLocked) != 0;               mSlideshow = null;               mAttachmentType = ATTACHMENT_TYPE_NOT_LOADED;               mDeliveryStatus = DeliveryStatus.NONE;               mReadReport = false;               mBody = null;               mMessageSize = 0;               mTextContentType = null;               mTimestamp = null;               mMmsStatus = cursor.getInt(columnsMap.mColumnMmsStatus);                  // Start an async load of the pdu. If the pdu is already loaded, the callback               // will get called immediately               boolean loadSlideshow = mMessageType != PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND;                  <strong>mItemLoadedFuture = MmsApp.getApplication().getPduLoaderManager()//異步加載幻燈片的邏輯                       .getPdu(mMessageUri, loadSlideshow,                       new PduLoadedMessageItemCallback());</strong>              } else {               throw new MmsException("Unknown type of the message: " + type);           }       }     在構造中,會根據信息的類別,加載短信和彩信的數據。數據包括信息的MessageUri,信息的 messageType,信息的主題,信息的boxId,信息的狀態等。這些屬於基礎信息,這些信息是要首先展示給用戶的。我們的目的是最後幾行加黑的代碼,他們就是我們彩信幻燈片後台加載的邏輯代碼。 MmsApp.java [java]   public PduLoaderManager getPduLoaderManager() {           return mPduLoaderManager;       }     PduLoadedManager.java [java]   public class PduLoaderManager extends BackgroundLoaderManager {.....}   [java]   public PduLoaderManager(final Context context) {           super(context);              mSlideshowCache = new SimpleCache<Uri, SlideshowModel>(8, 16, 0.75f, true);           mPduCache = PduCache.getInstance();           mPduPersister = PduPersister.getPduPersister(context);           mContext = context;       }   方法繼承子BackgroundLoadManager。 BackgroundLoadManager.java [java]   BackgroundLoaderManager(Context context) {           mPendingTaskUris = new HashSet<Uri>();<strong>//等待加載幻燈片任務集合,內容為彩信uri的集合</strong>           mCallbacks = new HashMap<Uri, Set<ItemLoadedCallback>>();<strong>//彩信uri為key,value是callback的集合,callback是在幻燈片附件加載任務完成後回調的方法對象。</strong>           final LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();           final int poolSize = MAX_THREADS;           mExecutor = new ThreadPoolExecutor(<strong>//開啟一個線程池,在新線程中處理幻燈片的加載等工作。</strong>                   poolSize, poolSize, 5, TimeUnit.SECONDS, queue,                   new BackgroundLoaderThreadFactory(getTag()));           mCallbackHandler = new Handler();       }   在上面的MessageItem類中,會調用PduLoadedManager類的getPdu方法。 [java]  public ItemLoadedFuture getPdu(Uri uri, boolean requestSlideshow,               final ItemLoadedCallback<PduLoaded> callback) {           if (uri == null) {               throw new NullPointerException();           }              PduCacheEntry cacheEntry = null;           synchronized(mPduCache) {               if (!mPduCache.isUpdating(uri)) {                   cacheEntry = mPduCache.get(uri);//第一次會走到這裡,cacheEntry為null。               }           }           final SlideshowModel slideshow = (requestSlideshow && !DEBUG_DISABLE_CACHE) ?//requestSlideshow為true,但mSlideshowCache.get(uri)為null。                   mSlideshowCache.get(uri) : null;              final boolean slideshowExists = (!requestSlideshow || slideshow != null);//判斷slideshowModel是否存在,slideshowModel是幻燈片的實體。           final boolean pduExists = (cacheEntry != null && cacheEntry.getPdu() != null);//pdu是否存在。pdu是幻燈片信息的封裝,基類是GenericPdu。           final boolean taskExists = mPendingTaskUris.contains(uri);//判斷是否存在線程           final boolean newTaskRequired = (!pduExists || !slideshowExists) && !taskExists;//是否需要新開啟線程           final boolean callbackRequired = (callback != null);//是否存在回調對象              if (pduExists && slideshowExists) {//如果pdu存在,並且slideshowModel也存在,那麼不用開啟線程加載了,直接返回。               if (callbackRequired) {                   PduLoaded pduLoaded = new PduLoaded(cacheEntry.getPdu(), slideshow);                   callback.onItemLoaded(pduLoaded, null);               }               return new NullItemLoadedFuture();           }              if (callbackRequired) {//如果存在回調對象,那麼將uri為key,value為callbacks的集合,加入到mCallbacks中。               addCallback(uri, callback);           }              if (newTaskRequired) {//是否需要開啟新的線程,如果需要,那麼構建一個PduTask,並且放到線程池中,執行它。               mPendingTaskUris.add(uri);               Runnable task = new PduTask(uri, requestSlideshow);               mExecutor.execute(task);           }           return new ItemLoadedFuture() {               public void cancel() {                   cancelCallback(callback);               }               public boolean isDone() {                   return false;               }           };       }   PduTask.java [java]  public class PduTask implements Runnable {           private final Uri mUri;           private final boolean mRequestSlideshow;              public PduTask(Uri uri, boolean requestSlideshow) {               if (uri == null) {                   throw new NullPointerException();               }               mUri = uri;               mRequestSlideshow = requestSlideshow;           }              /** {@inheritDoc} */           public void run() {               if (DEBUG_DISABLE_PDUS) {                   return;               }               if (DEBUG_LONG_WAIT) {                   try {                       Thread.sleep(10000);                   } catch (InterruptedException e) {                   }               }               GenericPdu pdu = null;//所有彩信pdu的基類,子類中有我們熟悉的SendReq(發送的彩信所包裝的pdu),RetrieveConf等               SlideshowModel slideshow = null;               Throwable exception = null;               try {                   pdu = mPduPersister.load(mUri);//<strong>特別關鍵的一個函數,在介紹完流程後,會介紹一下這個類的,處理的數據很多,但框架很清晰</strong>                   if (pdu != null && mRequestSlideshow) {                       slideshow = SlideshowModel.createFromPduBody(mContext,//從pdu中解析出SlideshowModel。從SlideshowModel能夠得到pdu,那麼反過來也一樣能夠得到。                               ((MultimediaMessagePdu)pdu).getBody());                   }               } catch (final MmsException e) {                   Log.e(TAG, "MmsException loading uri: " + mUri, e);                   exception = e;               }               final GenericPdu resultPdu = pdu;               final SlideshowModel resultSlideshow = slideshow;               final Throwable resultException = exception;               mCallbackHandler.post(new Runnable() {                   public void run() {                       final Set<ItemLoadedCallback> callbacks = mCallbacks.get(mUri);//我們在上面將回調對象的集合加入到了mCallbacks中,現在我們根據uri將回調對象集合取出來                       if (callbacks != null) {                           // Make a copy so that the callback can unregister itself                           for (final ItemLoadedCallback<PduLoaded> callback : asList(callbacks)) {                               if (Log.isLoggable(TAG, Log.DEBUG)) {                                   Log.d(TAG, "Invoking pdu callback " + callback);                               }                               PduLoaded pduLoaded = new PduLoaded(resultPdu, resultSlideshow);//遍歷集合,然後執行回調函數的onItemLoaded。                               callback.onItemLoaded(pduLoaded, resultException);                           }                       }                       // Add the slideshow to the soft cache if the load succeeded                       if (resultSlideshow != null) {                           mSlideshowCache.put(mUri, resultSlideshow);//將得到的slideshowModel作為value,uri作為key加入到mSlideshowCache中,下次就不需要開啟線程加載就可以得到SlideshowModel                       }                          mCallbacks.remove(mUri);//回調函數執行完畢,那麼從mCallbacks中移除                       mPendingTaskUris.remove(mUri);//同樣移除操作                          if (Log.isLoggable(LogTag.PDU_CACHE, Log.DEBUG)) {                           Log.d(TAG, "Pdu task for " + mUri + "exiting; " + mPendingTaskUris.size()                                   + " remain");                       }                   }               });           }       }     這個執行完畢,那麼我們回到MessageItem看看回調函數。 [java]  public class PduLoadedMessageItemCallback implements ItemLoadedCallback {           public void onItemLoaded(Object result, Throwable exception) {               if (exception != null) {                   Log.e(TAG, "PduLoadedMessageItemCallback PDU couldn't be loaded: ", exception);                   return;               }               PduLoaderManager.PduLoaded pduLoaded = (PduLoaderManager.PduLoaded)result;//回調的結果               long timestamp = 0L;               if (PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND == mMessageType) {//根據當前信息的類型,將pdu將強轉成相應的pdu封裝類。<strong>這裡我有一點疑惑(MessageItem中的mMessageType是會改變的,而我們的加載是異步加載,也就說加載前mMessageType == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND,如果我們加載完,mMessageType會不會變成另外一個值,比如PduHeaders.MESSAGE_TYPE_SEND_REQ等,那麼我們強轉會不會產生異常?就目前所知,在接收彩信時,MessageItem類型會發生改變,這種情況應該是會出現的)</strong>                   mDeliveryStatus = DeliveryStatus.NONE;                   NotificationInd notifInd = (NotificationInd)pduLoaded.mPdu;//強轉類型為NotificationInd,接收彩信時,為下載彩信內容                   interpretFrom(notifInd.getFrom(), mMessageUri);                   // Borrow the mBody to hold the URL of the message.                   mBody = new String(notifInd.getContentLocation());                   mMessageSize = (int) notifInd.getMessageSize();                   timestamp = notifInd.getExpiry() * 1000L;               } else {                   if (mCursor.isClosed()) {                       return;                   }                   MultimediaMessagePdu msg = (MultimediaMessagePdu)pduLoaded.mPdu;//MultimediaMessagePdu是發送和接收彩信的pdu類型的基類型。                   mSlideshow = pduLoaded.mSlideshow;                   mAttachmentType = MessageUtils.getAttachmentType(mSlideshow);                      if (mMessageType == PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF) {//接收彩信的類型,再往下就是繼續初始化一些彩信數據                       if (msg == null) {                           interpretFrom(null, mMessageUri);                       } else {                           RetrieveConf retrieveConf = (RetrieveConf) msg;                           interpretFrom(retrieveConf.getFrom(), mMessageUri);                           timestamp = retrieveConf.getDate() * 1000L;                       }                   } else {                       // Use constant string for outgoing messages                       mContact = mAddress =                               mContext.getString(R.string.messagelist_sender_self);                       timestamp = msg == null ? 0 : ((SendReq) msg).getDate() * 1000L;                   }                      SlideModel slide = mSlideshow == null ? null : mSlideshow.get(0);                   if ((slide != null) && slide.hasText()) {                       TextModel tm = slide.getText();                       mBody = tm.getText();                       mTextContentType = tm.getContentType();                   }                      mMessageSize = mSlideshow == null ? 0 : mSlideshow.getTotalMessageSize();                      String report = mCursor.getString(mColumnsMap.mColumnMmsDeliveryReport);                   if ((report == null) || !mAddress.equals(mContext.getString(                           R.string.messagelist_sender_self))) {                       mDeliveryStatus = DeliveryStatus.NONE;                   } else {                       int reportInt;                       try {                           reportInt = Integer.parseInt(report);                           if (reportInt == PduHeaders.VALUE_YES) {                               mDeliveryStatus = DeliveryStatus.RECEIVED;                           } else {                               mDeliveryStatus = DeliveryStatus.NONE;                           }                       } catch (NumberFormatException nfe) {                           Log.e(TAG, "Value for delivery report was invalid.");                           mDeliveryStatus = DeliveryStatus.NONE;                       }                   }                      report = mCursor.getString(mColumnsMap.mColumnMmsReadReport);                   if ((report == null) || !mAddress.equals(mContext.getString(                           R.string.messagelist_sender_self))) {                       mReadReport = false;                   } else {                       int reportInt;                       try {                           reportInt = Integer.parseInt(report);                           mReadReport = (reportInt == PduHeaders.VALUE_YES);                       } catch (NumberFormatException nfe) {                           Log.e(TAG, "Value for read report was invalid.");                           mReadReport = false;                       }                   }               }               if (!isOutgoingMessage()) {                   if (PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND == mMessageType) {                       mTimestamp = mContext.getString(R.string.expire_on,                               MessageUtils.formatTimeStampString(mContext, timestamp, mFullTimestamp));                   } else {                       mTimestamp =  MessageUtils.formatTimeStampString(mContext, timestamp, mFullTimestamp);                   }               }               if (mPduLoadedCallback != null) {                   mPduLoadedCallback.onPduLoaded(MessageItem.this);               }           }       }     異步加載完幻燈片,那麼就可以在彩信中顯示了。我們主要看幻燈片附件的異步加載,剩下的邏輯以後在分析。 我們最後來看一下 [java]   pdu = mPduPersister.load(mUri);   PduPersister.java 這個類在framework層 [java]   public GenericPdu load(Uri uri) throws MmsException {           GenericPdu pdu = null;           PduCacheEntry cacheEntry = null;           int msgBox = 0;           long threadId = -1;           try {               synchronized(PDU_CACHE_INSTANCE) {                   if (PDU_CACHE_INSTANCE.isUpdating(uri)) {                       if (LOCAL_LOGV) {                           Log.v(TAG, "load: " + uri + " blocked by isUpdating()");                       }                       try {                           PDU_CACHE_INSTANCE.wait();                       } catch (InterruptedException e) {                           Log.e(TAG, "load: ", e);                       }                       cacheEntry = PDU_CACHE_INSTANCE.get(uri);                       if (cacheEntry != null) {                           return cacheEntry.getPdu();                       }                   }                   // Tell the cache to indicate to other callers that this item                   // is currently being updated.                   PDU_CACHE_INSTANCE.setUpdating(uri, true);               }                 <strong> Cursor c = SqliteWrapper.query(mContext, mContentResolver, uri,//加載彩信數據庫中的內容                       PDU_PROJECTION, null, null, null);</strong>               PduHeaders headers = new PduHeaders();               Set<Entry<Integer, Integer>> set;               long msgId = ContentUris.parseId(uri);                  try {                   if ((c == null) || (c.getCount() != 1) || !c.moveToFirst()) {                       throw new MmsException("Bad uri: " + uri);                   }                      msgBox = c.getInt(PDU_COLUMN_MESSAGE_BOX);                   threadId = c.getLong(PDU_COLUMN_THREAD_ID);                      set = ENCODED_STRING_COLUMN_INDEX_MAP.entrySet();<strong>//解析數據庫中的內容到PduHeaders中。</strong>                   for (Entry<Integer, Integer> e : set) {                       setEncodedStringValueToHeaders(                               c, e.getValue(), headers, e.getKey());                   }                      set = TEXT_STRING_COLUMN_INDEX_MAP.entrySet();                   for (Entry<Integer, Integer> e : set) {                       setTextStringToHeaders(                               c, e.getValue(), headers, e.getKey());                   }                      set = OCTET_COLUMN_INDEX_MAP.entrySet();                   for (Entry<Integer, Integer> e : set) {                       setOctetToHeaders(                               c, e.getValue(), headers, e.getKey());                   }                      set = LONG_COLUMN_INDEX_MAP.entrySet();                   for (Entry<Integer, Integer> e : set) {                       setLongToHeaders(                               c, e.getValue(), headers, e.getKey());                   }               } finally {                   if (c != null) {                       c.close();                   }               }                  // Check whether 'msgId' has been assigned a valid value.               if (msgId == -1L) {                   throw new MmsException("Error! ID of the message: -1.");               }                  // Load address information of the MM.               loadAddress(msgId, headers);                  int msgType = headers.getOctet(PduHeaders.MESSAGE_TYPE);               <strong>PduBody body = new PduBody();                  // For PDU which type is M_retrieve.conf or Send.req, we should               // load multiparts and put them into the body of the PDU.               if ((msgType == PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF)                       || (msgType == PduHeaders.MESSAGE_TYPE_SEND_REQ)) {//構建pduBody                   PduPart[] parts = loadParts(msgId);//這部分相信大家可以看懂,同樣是加載數據庫                   if (parts != null) {                       int partsNum = parts.length;                       for (int i = 0; i < partsNum; i++) {                           body.addPart(parts[i]);                       }                   }               }</strong>                  switch (msgType) {<strong>//根據msgType,構建GeniricPdu的實例子類型</strong>               case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND:                   pdu = new NotificationInd(headers);                   break;               case PduHeaders.MESSAGE_TYPE_DELIVERY_IND:                   pdu = new DeliveryInd(headers);                   break;               case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND:                   pdu = new ReadOrigInd(headers);                   break;               case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF:                   pdu = new RetrieveConf(headers, body);                   break;               case PduHeaders.MESSAGE_TYPE_SEND_REQ:                   pdu = new SendReq(headers, body);                   break;               case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND:                   pdu = new AcknowledgeInd(headers);                   break;               case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND:                   pdu = new NotifyRespInd(headers);                   break;               case PduHeaders.MESSAGE_TYPE_READ_REC_IND:                   pdu = new ReadRecInd(headers);                   break;               case PduHeaders.MESSAGE_TYPE_SEND_CONF:               case PduHeaders.MESSAGE_TYPE_FORWARD_REQ:               case PduHeaders.MESSAGE_TYPE_FORWARD_CONF:               case PduHeaders.MESSAGE_TYPE_MBOX_STORE_REQ:               case PduHeaders.MESSAGE_TYPE_MBOX_STORE_CONF:               case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_REQ:               case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_CONF:               case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_REQ:               case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_CONF:               case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_REQ:               case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_CONF:               case PduHeaders.MESSAGE_TYPE_MBOX_DESCR:               case PduHeaders.MESSAGE_TYPE_DELETE_REQ:               case PduHeaders.MESSAGE_TYPE_DELETE_CONF:               case PduHeaders.MESSAGE_TYPE_CANCEL_REQ:               case PduHeaders.MESSAGE_TYPE_CANCEL_CONF:                   throw new MmsException(                           "Unsupported PDU type: " + Integer.toHexString(msgType));                  default:                   throw new MmsException(                           "Unrecognized PDU type: " + Integer.toHexString(msgType));               }           } finally {               synchronized(PDU_CACHE_INSTANCE) {                   if (pdu != null) {                       assert(PDU_CACHE_INSTANCE.get(uri) == null);                       // Update the cache entry with the real info                       cacheEntry = new PduCacheEntry(pdu, msgBox, threadId);                       PDU_CACHE_INSTANCE.put(uri, cacheEntry);                   }                   PDU_CACHE_INSTANCE.setUpdating(uri, false);                   PDU_CACHE_INSTANCE.notifyAll(); // tell anybody waiting on this entry to go ahead               }           }           return pdu;       }  
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved