signature:
public class NativeHelper { /** * Attempts to extract , from various sources , the applicable list of NDK architectures to support
 * as part of the build .
 * < br >
 * < br >
 * It retrieves the list from the following places :
 * < ul >
 * < li > ndkArchitecture parameter < / li >
 * < li > projects Application . mk - currently only a single architecture is supported by this method < / li >
 * < / ul >
 * @ param ndkArchitectures Space separated list of architectures . This may be from configuration or otherwise
 * @ param applicationMakefile The makefile ( Application . mk ) to retrieve the list from .
 * @ param basedir Directory the build is running from ( to resolve files )
 * @ return List of architectures to be supported by build .
 * @ throws MojoExecutionException */
public static String [ ] getNdkArchitectures ( final String ndkArchitectures , final String applicationMakefile , final File basedir ) throws MojoExecutionException { } }

implementation:
// if there is a specified ndk architecture , return it
if ( ndkArchitectures != null ) { return ndkArchitectures . split ( " " ) ; } // if there is no application makefile specified , let ' s use the default one
String applicationMakefileToUse = applicationMakefile ; if ( applicationMakefileToUse == null ) { applicationMakefileToUse = "jni/Application.mk" ; } // now let ' s see if the application file exists
File appMK = new File ( basedir , applicationMakefileToUse ) ; if ( appMK . exists ( ) ) { String [ ] foundNdkArchitectures = getAppAbi ( appMK ) ; if ( foundNdkArchitectures != null ) { return foundNdkArchitectures ; } } // return a default ndk architecture
return new String [ ] { "armeabi" } ;


signature:
public class NativeHelper { /** * Helper method for determining whether the specified architecture is a match for the
 * artifact using its classifier . When used for architecture matching , the classifier must be
 * formed by & lt ; architecture & gt ; - & lt ; classifier & gt ; .
 * If the artifact is legacy and defines no valid architecture , the artifact architecture will
 * default to < strong > armeabi < / strong > .
 * @ param ndkArchitecture Architecture to check for match
 * @ param artifact Artifact to check the classifier match for
 * @ return True if the architecture matches , otherwise false */
public static boolean artifactHasHardwareArchitecture ( Artifact artifact , String ndkArchitecture , String defaultArchitecture ) { } }

implementation: return Const . ArtifactType . NATIVE_SYMBOL_OBJECT . equals ( artifact . getType ( ) ) && ndkArchitecture . equals ( extractArchitectureFromArtifact ( artifact , defaultArchitecture ) ) ;


signature:
public class FileRetriever { /** * Finds the files in the supplied folder that match the configured includes .
 * @ param baseDirectory Directory to find files in .
 * @ return < code > String [ ] < / code > of the files ' paths and names , relative to < code > baseDirectory < / code > . Empty
 * < code > String [ ] < / code > if < code > baseDirectory < / code > does not exist . */
public String [ ] getFileNames ( File baseDirectory ) { } }

implementation: if ( ! baseDirectory . exists ( ) ) { return new String [ 0 ] ; } final DirectoryScanner directoryScanner = new DirectoryScanner ( ) ; directoryScanner . setBasedir ( baseDirectory ) ; directoryScanner . setIncludes ( includes ) ; directoryScanner . addDefaultExcludes ( ) ; directoryScanner . scan ( ) ; return directoryScanner . getIncludedFiles ( ) ;


signature:
public class DefaultJavaProcessExecutor { /** * Get the stderr / stdout outputs of a process and return when the process is done .
 * Both < b > must < / b > be read or the process will block on windows .
 * @ param process The process to get the output from .
 * @ param output The processOutput containing where to send the output .
 * Note that on Windows capturing the output is not optional . If output is null
 * the stdout / stderr will be captured and discarded .
 * @ return the process return code .
 * @ throws InterruptedException if { @ link Process # waitFor ( ) } was interrupted . */
private static int grabProcessOutput ( @ NonNull final Process process , @ NonNull final ProcessOutput output ) throws InterruptedException { } }

implementation:
Thread threadErr = new Thread ( "stderr" ) { @ Override public void run ( ) { InputStream stderr = process . getErrorStream ( ) ; OutputStream stream = output . getErrorOutput ( ) ; try { ByteStreams . copy ( stderr , stream ) ; stream . flush ( ) ; } catch ( IOException e ) { // ignore ?
} finally { try { Closeables . close ( stderr , true /* swallowIOException */
) ; } catch ( IOException e ) { // cannot happen
} try { Closeables . close ( stream , true /* swallowIOException */
) ; } catch ( IOException e ) { // cannot happen
} } } } ; Thread threadOut = new Thread ( "stdout" ) { @ Override public void run ( ) { InputStream stdout = process . getInputStream ( ) ; OutputStream stream = output . getStandardOutput ( ) ; try { ByteStreams . copy ( stdout , stream ) ; stream . flush ( ) ; } catch ( IOException e ) { // ignore ?
} finally { try { Closeables . close ( stdout , true /* swallowIOException */
) ; } catch ( IOException e ) { // cannot happen
} try { Closeables . close ( stream , true /* swallowIOException */
) ; } catch ( IOException e ) { // cannot happen
} } } } ; threadErr . start ( ) ; threadOut . start ( ) ; // it looks like on windows process # waitFor ( ) can return
// before the thread have filled the arrays , so we wait for both threads and the
// process itself .
threadErr . join ( ) ; threadOut . join ( ) ; // get the return code from the process
return process . waitFor ( ) ;


signature:
public class DES { /** * Convert data to encrypted hex string
 * @ param data data to encrypt
 * @ param key encrypt key
 * @ return hex string */
public static String encrypt ( String data , String key ) { } }

implementation: try { Cipher c = Cipher . getInstance ( "DES/ECB/PKCS5Padding" ) ; c . init ( Cipher . ENCRYPT_MODE , SecretKeyFactory . getInstance ( "DES" ) . generateSecret ( new DESKeySpec ( key . getBytes ( ) ) ) ) ; return Hex . encodeHexString ( c . doFinal ( data . getBytes ( ) ) ) ; } catch ( Exception e ) { e . printStackTrace ( ) ; } return null ;


signature:
public class DES { /** * Convert encrypted hex string to UTF - 8 string
 * @ param data data to decrypt
 * @ param key decrypt key
 * @ return UTF - 8 string */
public static String decrypt ( String data , String key ) { } }

implementation: try { Cipher c = Cipher . getInstance ( "DES/ECB/PKCS5Padding" ) ; c . init ( Cipher . DECRYPT_MODE , SecretKeyFactory . getInstance ( "DES" ) . generateSecret ( new DESKeySpec ( key . getBytes ( ) ) ) ) ; return new String ( c . doFinal ( Hex . decodeHex ( data . toCharArray ( ) ) ) , Charset . defaultCharset ( ) ) ; } catch ( Exception e ) { e . printStackTrace ( ) ; } return null ;


signature:
public class DnsMessage { /** * Parse a domain name starting at the current offset and moving the input
 * stream pointer past this domain name ( even if cross references occure ) .
 * @ param dis The input stream .
 * @ param data The raw data ( for cross references ) .
 * @ return The domain name string .
 * @ throws IOException Should never happen . */
private static String readName ( DataInputStream dis , byte data [ ] ) throws IOException { } }

implementation: int c = dis . readUnsignedByte ( ) ; if ( ( c & 0xc0 ) == 0xc0 ) { c = ( ( c & 0x3f ) << 8 ) + dis . readUnsignedByte ( ) ; HashSet < Integer > jumps = new HashSet < Integer > ( ) ; jumps . add ( c ) ; return readName ( data , c , jumps ) ; } if ( c == 0 ) { return "" ; } byte b [ ] = new byte [ c ] ; dis . readFully ( b ) ; String s = IDN . toUnicode ( new String ( b ) ) ; String t = readName ( dis , data ) ; if ( t . length ( ) > 0 ) { s = s + "." + t ; } return s ;


signature:
public class DnsMessage { /** * Parse a domain name starting at the given offset .
 * @ param data The raw data .
 * @ param offset The offset .
 * @ param jumps The list of jumps ( by now ) .
 * @ return The parsed domain name .
 * @ throws IOException on cycles . */
private static String readName ( byte data [ ] , int offset , HashSet < Integer > jumps ) throws IOException { } }

implementation: int c = data [ offset ] & 0xff ; if ( ( c & 0xc0 ) == 0xc0 ) { c = ( ( c & 0x3f ) << 8 ) + ( data [ offset + 1 ] & 0xff ) ; if ( jumps . contains ( c ) ) { throw new DnsException ( "" , "Cyclic offsets detected." ) ; } jumps . add ( c ) ; return readName ( data , c , jumps ) ; } if ( c == 0 ) { return "" ; } String s = new String ( data , offset + 1 , c ) ; String t = readName ( data , offset + 1 + c , jumps ) ; if ( t . length ( ) > 0 ) { s = s + "." + t ; } return s ;


signature:
public class Hex { /** * Converts a hexadecimal character to an integer .
 * @ param ch A character to convert to an integer digit
 * @ param index The index of the character in the source
 * @ return An integer
 * @ throws HexDecodeException Thrown if ch is an illegal hex character */
protected static int toDigit ( final char ch , final int index ) throws HexDecodeException { } }

implementation: final int digit = Character . digit ( ch , 16 ) ; if ( digit == - 1 ) { throw new HexDecodeException ( "Illegal hexadecimal character " + ch + " at index " + index ) ; } return digit ;


signature:
public class DnsManager { /** * 简单通过时区判断是否在大陆 */
public static boolean needHttpDns ( ) { } }

implementation: try { TimeZone zone = TimeZone . getDefault ( ) ; String id = zone . getID ( ) ; return ( "Asia/Shanghai" . equals ( id ) || "Asia/Chongqing" . equals ( id ) || "Asia/Harbin" . equals ( id ) || "Asia/Urumqi" . equals ( id ) ) ; } catch ( Exception e ) { return false ; }


signature:
public class DnsManager { /** * 当网络发生变化时 , 通知当前的网络信息
 * @ param info 网络信息 */
public void onNetworkChange ( NetworkInfo info ) { } }

implementation: clearCache ( ) ; this . info = info == null ? NetworkInfo . normal : info ; synchronized ( resolvers ) { index = 0 ; }


signature:
public class DnsManager { /** * 插入指定运营商的hosts配置
 * @ param domain 域名
 * @ param ip ip
 * @ param provider 运营商 , 见 NetworkInfo
 * @ return 当前的DnsManager , 便于链式调用 */
public DnsManager putHosts ( String domain , String ip , int provider ) { } }

implementation: hosts . put ( domain , new Hosts . Value ( ip , provider ) ) ; return this ;


signature:
public class DnsManager { /** * 插入指定运营商的hosts配置
 * @ param domain 域名
 * @ param ip ip
 * @ return 当前的DnsManager , 便于链式调用 */
public DnsManager putHosts ( String domain , String ip ) { } }

implementation: hosts . put ( domain , ip ) ; return this ;


signature:
public class ScrollHeaderFrame { /** * if deltaY > 0 , tryToMove the content down */
private boolean tryToMove ( float deltaY ) { } }

implementation:
// has reached the bottom
if ( ( deltaY > 0 && mCurrentPos == 0 ) ) { if ( DEBUG ) { Log . d ( LOG_TAG , String . format ( "has reached the bottom" ) ) ; } return false ; } // has reached the top
if ( ( deltaY < 0 && mCurrentPos == - mHeaderHeight ) ) { if ( DEBUG ) { Log . d ( LOG_TAG , String . format ( "has reached the top" ) ) ; } return false ; } int to = mCurrentPos + ( int ) deltaY ; // over top
if ( to < - mHeaderHeight ) { if ( DEBUG ) { Log . d ( LOG_TAG , String . format ( "over top" ) ) ; } to = - mHeaderHeight ; } // over bottom
if ( to > 0 ) { if ( DEBUG ) { Log . d ( LOG_TAG , String . format ( "over bottom" ) ) ; } to = 0 ; } return moveTo ( to ) ;


signature:
public class NetworkStatusManager { /** * { @ link TelephonyManager # getNetworkClass } */
private static int getMobileNetworkClass ( int networkType ) { } }

implementation: switch ( networkType ) { case TelephonyManager . NETWORK_TYPE_GPRS : case TelephonyManager . NETWORK_TYPE_EDGE : case TelephonyManager . NETWORK_TYPE_CDMA : case TelephonyManager . NETWORK_TYPE_1xRTT : case TelephonyManager . NETWORK_TYPE_IDEN : return NETWORK_CLASS_2G ; case TelephonyManager . NETWORK_TYPE_UMTS : case TelephonyManager . NETWORK_TYPE_EVDO_0 : case TelephonyManager . NETWORK_TYPE_EVDO_A : case TelephonyManager . NETWORK_TYPE_HSDPA : case TelephonyManager . NETWORK_TYPE_HSUPA : case TelephonyManager . NETWORK_TYPE_HSPA : case TelephonyManager . NETWORK_TYPE_EVDO_B : case TelephonyManager . NETWORK_TYPE_EHRPD : case TelephonyManager . NETWORK_TYPE_HSPAP : return NETWORK_CLASS_3G ; case TelephonyManager . NETWORK_TYPE_LTE : return NETWORK_CLASS_4G ; default : return NETWORK_CLASS_UNKNOWN ; }


signature:
public class NetworkStatusManager { /** * 2G / 3G / 4G / WIFI
 * @ return */
public int getNetworkType ( ) { } }

implementation:
NetworkInfo activeNetworkInfo = getNetworkInfo ( ) ; if ( activeNetworkInfo != null ) { // WIFI
if ( activeNetworkInfo . getType ( ) == ConnectivityManager . TYPE_WIFI ) { return NETWORK_CLASS_WIFI ; } // MOBILE
else if ( activeNetworkInfo . getType ( ) == ConnectivityManager . TYPE_MOBILE ) { return getMobileNetworkClass ( activeNetworkInfo . getSubtype ( ) ) ; } } return NETWORK_CLASS_UNKNOWN ;


signature:
public class NetworkStatusManager { /** * This method starts listening for network connectivity state changes .
 * @ param context */
public synchronized void startListening ( Context context ) { } }

implementation: if ( ! mListening ) { mContext = context ; IntentFilter filter = new IntentFilter ( ) ; filter . addAction ( ConnectivityManager . CONNECTIVITY_ACTION ) ; context . registerReceiver ( mReceiver , filter ) ; mListening = true ; }


signature:
public class NetworkStatusManager { /** * This method stops this class from listening for network changes . */
public synchronized void stopListening ( ) { } }

implementation: if ( mListening ) { mContext . unregisterReceiver ( mReceiver ) ; mContext = null ; mNetworkInfo = null ; mOtherNetworkInfo = null ; mIsFailOver = false ; mReason = null ; mListening = false ; }


signature:
public class MultiPartRequestSender { /** * post data to Server */
public void send ( ) throws IOException { } }

implementation:
HashMap < String , RequestData . UploadFileInfo > uploadFiles = mRequestData . getUploadFiles ( ) ; HashMap < String , Object > mPostData = mRequestData . getPostData ( ) ; // send data to Server
if ( mPostData != null && mPostData . size ( ) != 0 ) { Iterator < Map . Entry < String , Object > > iterator = mPostData . entrySet ( ) . iterator ( ) ; while ( iterator . hasNext ( ) ) { Map . Entry < String , Object > item = iterator . next ( ) ; Object value = item . getValue ( ) ; if ( value == null ) { value = "" ; } addFormField ( item . getKey ( ) , value . toString ( ) ) ; } } // send file to server
Iterator < Map . Entry < String , RequestData . UploadFileInfo > > iterator = uploadFiles . entrySet ( ) . iterator ( ) ; while ( iterator . hasNext ( ) ) { Map . Entry < String , RequestData . UploadFileInfo > item = iterator . next ( ) ; RequestData . UploadFileInfo uploadFileInfo = item . getValue ( ) ; addFilePart ( uploadFileInfo . fieldName , uploadFileInfo . uploadFile , uploadFileInfo . fileName ) ; }


signature:
public class MultiPartRequestSender { /** * Adds a form field to the request
 * @ param name field name
 * @ param value field value */
public void addFormField ( String name , String value ) { } }

implementation: mWriter . append ( "--" + mBoundary ) . append ( LINE_FEED ) ; mWriter . append ( "Content-Disposition: form-data; name=\"" + name + "\"" ) . append ( LINE_FEED ) ; mWriter . append ( "Content-Type: text/plain; charset=" + mCharset ) . append ( LINE_FEED ) ; mWriter . append ( LINE_FEED ) ; mWriter . append ( value ) . append ( LINE_FEED ) ; mWriter . flush ( ) ;


signature:
public class MultiPartRequestSender { /** * Adds a upload file section to the request
 * @ param fieldName name attribute in < input type = " file " name = " . . . " / >
 * @ param uploadFile a File to be uploaded
 * @ param fileName the filename field
 * @ throws IOException */
public void addFilePart ( String fieldName , File uploadFile , String fileName ) throws IOException { } }

implementation: if ( TextUtils . isEmpty ( fileName ) ) { fileName = uploadFile . getName ( ) ; } mWriter . append ( "--" + mBoundary ) . append ( LINE_FEED ) ; mWriter . append ( "Content-Disposition: form-data; name=\"" + fieldName + "\"; filename=\"" + fileName + "\"" ) . append ( LINE_FEED ) ; mWriter . append ( "Content-Type: " + URLConnection . guessContentTypeFromName ( fileName ) ) . append ( LINE_FEED ) ; mWriter . append ( "Content-Transfer-Encoding: binary" ) . append ( LINE_FEED ) ; mWriter . append ( LINE_FEED ) ; mWriter . flush ( ) ; FileInputStream inputStream = new FileInputStream ( uploadFile ) ; byte [ ] buffer = new byte [ 4096 ] ; int bytesRead = - 1 ; while ( ( bytesRead = inputStream . read ( buffer ) ) != - 1 ) { mOutputStream . write ( buffer , 0 , bytesRead ) ; } mOutputStream . flush ( ) ; inputStream . close ( ) ; mWriter . append ( LINE_FEED ) ; mWriter . flush ( ) ;


signature:
public class ImageProvider { /** * Get the size in bytes of a bitmap in a BitmapDrawable . Note that from Android 4.4 ( KitKat ) onward this returns the allocated memory size of the bitmap which can be larger than the actual bitmap data byte count ( in the case it was re - used ) .
 * @ param value
 * @ return size in bytes */
@ TargetApi ( 19 ) // @ TargetApi ( VERSION _ CODES . KITKAT )
public static long getBitmapSize ( BitmapDrawable value ) { } }

implementation:
if ( null == value ) { return 0 ; } Bitmap bitmap = value . getBitmap ( ) ; // From KitKat onward use getAllocationByteCount ( ) as allocated bytes can potentially be
// larger than bitmap byte count .
if ( Version . hasKitKat ( ) ) { return bitmap . getAllocationByteCount ( ) ; } if ( Version . hasHoneycombMR1 ( ) ) { return bitmap . getByteCount ( ) ; } // Pre HC - MR1
return bitmap . getRowBytes ( ) * bitmap . getHeight ( ) ;


signature:
public class ImageProvider { /** * Create a BitmapDrawable which can be managed in ImageProvider
 * @ param resources
 * @ param bitmap
 * @ return */
public BitmapDrawable createBitmapDrawable ( Resources resources , Bitmap bitmap ) { } }

implementation:
if ( bitmap == null ) { return null ; } BitmapDrawable drawable = null ; if ( bitmap != null ) { if ( Version . hasHoneycomb ( ) ) { // Running on Honeycomb or newer , so wrap in a standard BitmapDrawable
drawable = new BitmapDrawable ( resources , bitmap ) ; } else { // Running on Gingerbread or older , so wrap in a RecyclingBitmapDrawable
// which will recycle automatically
drawable = new RecyclingBitmapDrawable ( resources , bitmap ) ; } } return drawable ;


signature:
public class ImageProvider { /** * Get from memory cache . */
public BitmapDrawable getBitmapFromMemCache ( ImageTask imageTask ) { } }

implementation: BitmapDrawable memValue = null ; if ( mMemoryCache != null ) { memValue = mMemoryCache . get ( imageTask . getIdentityKey ( ) ) ; } return memValue ;


signature:
public class ImageProvider { /** * Get Bitmap . If not exist in file cache , will try to re - use the file cache of the other sizes .
 * If no file cache can be used , download then save to file . */
public Bitmap fetchBitmapData ( ImageLoader imageLoader , ImageTask imageTask , ImageReSizer imageReSizer ) { } }

implementation:
Bitmap bitmap = null ; if ( mDiskCacheProvider == null ) { return null ; } FileInputStream inputStream = null ; String fileCacheKey = imageTask . getFileCacheKey ( ) ; ImageReuseInfo reuseInfo = imageTask . getRequest ( ) . getImageReuseInfo ( ) ; if ( DEBUG ) { Log . d ( TAG , String . format ( MSG_FETCH_BEGIN , imageTask ) ) ; Log . d ( TAG , String . format ( MSG_FETCH_BEGIN_IDENTITY_KEY , imageTask , imageTask . getIdentityKey ( ) ) ) ; Log . d ( TAG , String . format ( MSG_FETCH_BEGIN_FILE_CACHE_KEY , imageTask , fileCacheKey ) ) ; Log . d ( TAG , String . format ( MSG_FETCH_BEGIN_ORIGIN_URL , imageTask , imageTask . getOriginUrl ( ) ) ) ; Log . d ( TAG , String . format ( MSG_FETCH_BEGIN_IDENTITY_URL , imageTask , imageTask . getIdentityUrl ( ) ) ) ; } // read from file cache
inputStream = mDiskCacheProvider . getInputStream ( fileCacheKey ) ; // try to reuse
if ( inputStream == null ) { if ( reuseInfo != null && reuseInfo . getReuseSizeList ( ) != null && reuseInfo . getReuseSizeList ( ) . length > 0 ) { if ( DEBUG ) { Log . d ( TAG , String . format ( MSG_FETCH_TRY_REUSE , imageTask ) ) ; } final String [ ] sizeKeyList = reuseInfo . getReuseSizeList ( ) ; for ( int i = 0 ; i < sizeKeyList . length ; i ++ ) { String size = sizeKeyList [ i ] ; final String key = imageTask . generateFileCacheKeyForReuse ( size ) ; inputStream = mDiskCacheProvider . getInputStream ( key ) ; if ( inputStream != null ) { if ( DEBUG ) { Log . d ( TAG , String . format ( MSG_FETCH_REUSE_SUCCESS , imageTask , size ) ) ; } break ; } else { if ( DEBUG ) { Log . d ( TAG , String . format ( MSG_FETCH_REUSE_FAIL , imageTask , size , key ) ) ; } } } } } else { if ( DEBUG ) { Log . d ( TAG , String . format ( MSG_FETCH_HIT_DISK_CACHE , imageTask ) ) ; } } if ( imageTask . getStatistics ( ) != null ) { imageTask . getStatistics ( ) . s2_afterCheckFileCache ( inputStream != null ) ; } // We ' ve got nothing from file cache
if ( inputStream == null ) { String url = imageReSizer . getRemoteUrl ( imageTask ) ; if ( DEBUG ) { Log . d ( TAG , String . format ( MSG_FETCH_DOWNLOAD , imageTask , url ) ) ; } inputStream = mDiskCacheProvider . downloadAndGetInputStream ( imageLoader . getImageDownloader ( ) , imageTask , fileCacheKey , url ) ; if ( imageTask . getStatistics ( ) != null ) { imageTask . getStatistics ( ) . s3_afterDownload ( ) ; } if ( inputStream == null ) { imageTask . setError ( ImageTask . ERROR_NETWORK ) ; CLog . e ( TAG , "%s download fail: %s %s" , imageTask , fileCacheKey , url ) ; } } if ( inputStream != null ) { try { bitmap = decodeSampledBitmapFromDescriptor ( inputStream . getFD ( ) , imageTask , imageReSizer ) ; if ( bitmap == null ) { imageTask . setError ( ImageTask . ERROR_BAD_FORMAT ) ; CLog . e ( TAG , "%s decode bitmap fail, bad format. %s, %s" , imageTask , fileCacheKey , imageReSizer . getRemoteUrl ( imageTask ) ) ; } } catch ( IOException e ) { CLog . e ( TAG , "%s decode bitmap fail, may be out of memory. %s, %s" , imageTask , fileCacheKey , imageReSizer . getRemoteUrl ( imageTask ) ) ; if ( CubeDebug . DEBUG_IMAGE ) { e . printStackTrace ( ) ; } } } else { CLog . e ( TAG , "%s fetch bitmap fail. %s, %s" , imageTask , fileCacheKey , imageReSizer . getRemoteUrl ( imageTask ) ) ; } if ( imageTask != null && imageTask . getStatistics ( ) != null ) { imageTask . getStatistics ( ) . s4_afterDecode ( mDiskCacheProvider . getSize ( fileCacheKey ) ) ; } return bitmap ;


signature:
public class ImageLoaderFactory { /** * customize cache
 * @ param context
 * @ param memoryCacheSizeInKB How many memory should use . Will not be greater than 50 % of free memory
 * @ param defaultDiskCachePath Default image cache path .
 * Absolute path or a relative path under cache directory . External cache first .
 * If not specified , using { @ link # DEFAULT _ FILE _ CACHE _ DIR } under cache directory .
 * @ param defaultDiskCacheSizeInKB Default disk cache size . */
public static void customizeCache ( Context context , int memoryCacheSizeInKB , String defaultDiskCachePath , int defaultDiskCacheSizeInKB ) { } }

implementation: customizeCache ( context , memoryCacheSizeInKB , defaultDiskCachePath , defaultDiskCacheSizeInKB , null , 0 ) ;


signature:
public class ImageLoaderFactory { /** * customize cache
 * @ param context
 * @ param memoryCacheSizeInKB How many memory should use . Will not be greater than 50 % of free memory
 * @ param defaultDiskCacheSizeInKB Default disk cache size .
 * @ param stableDiskCacheSizeInKB Stable disk cache size . */
public static void customizeCache ( Context context , int memoryCacheSizeInKB , int defaultDiskCacheSizeInKB , int stableDiskCacheSizeInKB ) { } }

implementation: customizeCache ( context , memoryCacheSizeInKB , null , defaultDiskCacheSizeInKB , null , stableDiskCacheSizeInKB ) ;


signature:
public class ImageLoaderFactory { /** * customize cache
 * @ param context
 * @ param memoryCacheSizeInKB How many memory should use . Will not be greater than 50 % of free memory
 * @ param defaultDiskCachePath Default image cache path .
 * Absolute path or a relative path under cache directory . External cache first .
 * If not specified , using { @ link # DEFAULT _ FILE _ CACHE _ DIR } under cache directory .
 * @ param defaultDiskCacheSizeInKB Default disk cache size .
 * @ param stableDiskCachePath Path for stable cache directory . Default is { @ link # STABLE _ FILE _ CACHE _ DIR }
 * @ param stableDiskCacheSizeInKB Stable disk cache size . */
public static void customizeCache ( Context context , int memoryCacheSizeInKB , String defaultDiskCachePath , int defaultDiskCacheSizeInKB , String stableDiskCachePath , int stableDiskCacheSizeInKB ) { } }

implementation:
// init memory cache first
if ( memoryCacheSizeInKB > 0 ) { int maxCacheSizeInKB = Math . round ( 0.5f * Runtime . getRuntime ( ) . maxMemory ( ) / 1024 ) ; memoryCacheSizeInKB = Math . min ( memoryCacheSizeInKB , maxCacheSizeInKB ) ; sDefaultImageMemoryCache = new DefaultMemoryCache ( memoryCacheSizeInKB ) ; } if ( defaultDiskCacheSizeInKB > 0 && ! TextUtils . isEmpty ( defaultDiskCachePath ) ) { ImageDiskCacheProvider imageFileProvider = getImageFileProvider ( context , defaultDiskCachePath , defaultDiskCacheSizeInKB , DEFAULT_FILE_CACHE_DIR ) ; if ( imageFileProvider != null ) { sDefaultImageProvider = new ImageProvider ( context , getDefaultImageMemoryCache ( ) , imageFileProvider ) ; } } if ( stableDiskCacheSizeInKB > 0 && ! TextUtils . isEmpty ( stableDiskCachePath ) ) { ImageDiskCacheProvider imageFileProvider = getImageFileProvider ( context , stableDiskCachePath , stableDiskCacheSizeInKB , STABLE_FILE_CACHE_DIR ) ; if ( imageFileProvider != null ) { sStableImageProvider = new ImageProvider ( context , getDefaultImageMemoryCache ( ) , imageFileProvider ) ; } }


signature:
public class ImageLoader { /** * Load the image in advance . */
public void preLoadImages ( String [ ] urls ) { } }

implementation: int len = urls . length ; for ( int i = 0 ; i < len ; i ++ ) { ImageLoadRequest request = new ImageLoadRequest ( urls [ i ] ) ; final ImageTask imageTask = createImageTask ( request ) ; imageTask . setIsPreLoad ( ) ; addImageTask ( imageTask , null ) ; }


signature:
public class ImageLoader { /** * Create an ImageTask .
 * You can override this method to return a customized { @ link ImageTask } .
 * @ param url
 * @ param requestWidth
 * @ param requestHeight
 * @ param imageReuseInfo
 * @ return */
@ Deprecated public ImageTask createImageTask ( String url , int requestWidth , int requestHeight , ImageReuseInfo imageReuseInfo ) { } }

implementation: ImageTask imageTask = ImageTask . obtain ( ) ; if ( imageTask == null ) { imageTask = new ImageTask ( ) ; } ImageLoadRequest imageLoadRequest = new ImageLoadRequest ( url , requestWidth , requestHeight , - 1 , imageReuseInfo ) ; imageTask . renewForRequest ( imageLoadRequest ) ; return imageTask ;


signature:
public class ImageLoader { /** * Detach the ImageView from the ImageTask .
 * @ param imageTask
 * @ param imageView */
public void detachImageViewFromImageTask ( ImageTask imageTask , CubeImageView imageView ) { } }

implementation: imageTask . removeImageView ( imageView ) ; if ( imageTask . isLoading ( ) ) { if ( ! imageTask . isPreLoad ( ) && ! imageTask . stillHasRelatedImageView ( ) ) { LoadImageTask task = mLoadWorkList . get ( imageTask . getIdentityKey ( ) ) ; if ( task != null ) { task . cancel ( ) ; } if ( DEBUG ) { CLog . d ( LOG_TAG , "%s previous work is cancelled." , imageTask ) ; } } } if ( ! imageTask . stillHasRelatedImageView ( ) ) { imageTask . tryToRecycle ( ) ; }


signature:
public class ImageLoader { /** * Add the ImageTask into loading list .
 * @ param imageTask
 * @ param imageView */
public void addImageTask ( ImageTask imageTask , CubeImageView imageView ) { } }

implementation: if ( ! mHasBeenAddedToComponentManager ) { CLog . w ( LOG_TAG , "ImageLoader has not been add to a Component Manager." , this ) ; } LoadImageTask runningTask = mLoadWorkList . get ( imageTask . getIdentityKey ( ) ) ; if ( runningTask != null ) { if ( imageView != null ) { if ( DEBUG ) { CLog . d ( LOG_TAG , MSG_ATTACK_TO_RUNNING_TASK , imageTask , runningTask . getImageTask ( ) ) ; } runningTask . getImageTask ( ) . addImageView ( imageView ) ; runningTask . getImageTask ( ) . notifyLoading ( mImageLoadHandler , imageView ) ; } return ; } else { imageTask . addImageView ( imageView ) ; } imageTask . onLoading ( mImageLoadHandler ) ; LoadImageTask loadImageTask = createLoadImageTask ( imageTask ) ; mLoadWorkList . put ( imageTask . getIdentityKey ( ) , loadImageTask ) ; mImageTaskExecutor . execute ( loadImageTask ) ;


signature:
public class ImageLoader { /** * Check weather this imageTask has cache Drawable data . */
public boolean queryCache ( ImageTask imageTask , CubeImageView imageView ) { } }

implementation: if ( null == mImageProvider ) { return false ; } BitmapDrawable drawable = mImageProvider . getBitmapFromMemCache ( imageTask ) ; if ( imageTask . getStatistics ( ) != null ) { imageTask . getStatistics ( ) . s0_afterCheckMemoryCache ( drawable != null ) ; } if ( drawable == null ) { return false ; } if ( DEBUG ) { CLog . d ( LOG_TAG , MSG_HIT_CACHE , imageTask , drawable . getIntrinsicWidth ( ) , drawable . getIntrinsicHeight ( ) ) ; } imageTask . addImageView ( imageView ) ; imageTask . onLoadTaskFinish ( drawable , mImageLoadHandler ) ; return true ;


signature:
public class ImageLoader { /** * Recover the from the work list */
public void recoverWork ( ) { } }

implementation: if ( DEBUG ) { CLog . d ( LOG_TAG , "work_status: recoverWork %s" , this ) ; } mExitTasksEarly = false ; setPause ( false ) ; Iterator < Entry < String , LoadImageTask > > it = ( Iterator < Entry < String , LoadImageTask > > ) mLoadWorkList . entrySet ( ) . iterator ( ) ; while ( it . hasNext ( ) ) { Entry < String , LoadImageTask > item = it . next ( ) ; LoadImageTask task = item . getValue ( ) ; task . restart ( ) ; mImageTaskExecutor . execute ( task ) ; }


signature:
public class ImageLoader { /** * Drop all the work , and leave it in the work list . */
public void stopWork ( ) { } }

implementation: if ( DEBUG ) { CLog . d ( LOG_TAG , "work_status: stopWork %s" , this ) ; } mExitTasksEarly = true ; setPause ( false ) ; flushFileCache ( ) ;


signature:
public class ImageLoader { /** * Drop all the work , clear the work list . */
public void destroy ( ) { } }

implementation: if ( DEBUG ) { CLog . d ( LOG_TAG , "work_status: destroy %s" , this ) ; } mExitTasksEarly = true ; setPause ( false ) ; Iterator < Entry < String , LoadImageTask > > it = ( Iterator < Entry < String , LoadImageTask > > ) mLoadWorkList . entrySet ( ) . iterator ( ) ; while ( it . hasNext ( ) ) { Entry < String , LoadImageTask > item = it . next ( ) ; final LoadImageTask task = item . getValue ( ) ; it . remove ( ) ; if ( task != null ) { task . cancel ( ) ; } } mLoadWorkList . clear ( ) ;


signature:
public class ImageLoader { /** * try to attach to { @ link in . srain . cube . app . lifecycle . IComponentContainer } */
public ImageLoader tryToAttachToContainer ( Object object , boolean throwEx ) { } }

implementation: if ( LifeCycleComponentManager . tryAddComponentToContainer ( this , object , throwEx ) ) { mHasBeenAddedToComponentManager = true ; } return this ;


signature:
public class ImageLoader { /** * LiefCycle phase will be same to CubeFragment , an will be processed automatically .
 * @ param fragment
 * @ return */
public ImageLoader attachToCubeFragment ( CubeFragment fragment ) { } }

implementation: if ( fragment != null ) { if ( LifeCycleComponentManager . tryAddComponentToContainer ( this , fragment , true ) ) { mHasBeenAddedToComponentManager = true ; } } return this ;


signature:
public class CacheManager { /** * delete cache by key
 * @ param key */
public void invalidateCache ( String key ) { } }

implementation: if ( DEBUG ) { CLog . d ( LOG_TAG , "key: %s, invalidateCache" , key ) ; } try { mFileCache . getDiskCache ( ) . delete ( key ) ; } catch ( IOException e ) { if ( DEBUG ) { e . printStackTrace ( ) ; } } mMemoryCache . remove ( key ) ;


signature:
public class CacheManager { /** * clear the disk cache */
public void clearDiskCache ( ) { } }

implementation: if ( null != mFileCache ) { try { mFileCache . getDiskCache ( ) . clear ( ) ; } catch ( IOException e ) { if ( DEBUG ) { e . printStackTrace ( ) ; } } }


signature:
public class CacheManager { /** * Request cache synchronously .
 * If there is not cache data available , return null ,
 * and { @ link ICacheAble # onNoCacheData } will not no be called .
 * @ param cacheAble
 * @ param < T >
 * @ return if not cache data available , return null , { @ link ICacheAble # onNoCacheData } will not no be called . */
@ SuppressWarnings ( { } }

implementation:
"unused" } ) public < T > T requestCacheSync ( ICacheAble < T > cacheAble ) { if ( cacheAble . cacheIsDisabled ( ) ) { return null ; } // try to find in runtime cache
String cacheKey = cacheAble . getCacheKey ( ) ; CacheMetaData mRawData = mMemoryCache . get ( cacheKey ) ; if ( mRawData != null ) { if ( DEBUG ) { CLog . d ( LOG_TAG , "key: %s, exist in list" , cacheKey ) ; } } // try read from cache data
if ( mRawData == null ) { boolean hasFileCache = mFileCache . getDiskCache ( ) . has ( cacheKey ) ; if ( hasFileCache ) { String cacheContent = mFileCache . read ( cacheKey ) ; JsonData jsonData = JsonData . create ( cacheContent ) ; mRawData = CacheMetaData . createFromJson ( jsonData ) ; } } // try to read from assets cache file
if ( mRawData == null ) { String assertInitDataPath = cacheAble . getAssertInitDataPath ( ) ; if ( assertInitDataPath != null && assertInitDataPath . length ( ) > 0 ) { String cacheContent = DiskFileUtils . readAssert ( mContext , assertInitDataPath ) ; if ( ! TextUtils . isEmpty ( cacheContent ) ) { mRawData = CacheMetaData . createInvalidated ( cacheContent ) ; putDataToMemoryCache ( cacheKey , mRawData ) ; } } } if ( mRawData != null ) { boolean outOfDate = mRawData . isOutOfDateFor ( cacheAble ) ; if ( outOfDate && ! cacheAble . useCacheAnyway ( ) ) { return null ; } JsonData data = JsonData . create ( mRawData . getData ( ) ) ; T ret = cacheAble . processRawDataFromCache ( data ) ; cacheAble . onCacheData ( CacheResultType . FROM_INIT_FILE , ret , outOfDate ) ; return ret ; } if ( DEBUG ) { CLog . d ( LOG_TAG , "key: %s, cache file not exist" , cacheKey ) ; } return null ;


signature:
public class SimpleHashSet { /** * Allocate a table of the given capacity and set the threshold accordingly .
 * @ param newCapacity must be a power of two */
private SimpleHashSetEntry < T > [ ] makeTable ( int newCapacity ) { } }

implementation:
@ SuppressWarnings ( "unchecked" ) SimpleHashSetEntry < T > [ ] newTable = ( SimpleHashSetEntry < T > [ ] ) new SimpleHashSetEntry [ newCapacity ] ; mTable = newTable ; threshold = ( newCapacity >> 1 ) + ( newCapacity >> 2 ) ; // 3/4 capacity
return newTable ;


signature:
public class SimpleHashSet { /** * Doubles the capacity of the hash table . Existing entries are placed in
 * the correct bucket on the enlarged table . If the current capacity is ,
 * MAXIMUM _ CAPACITY , this method is a no - op . Returns the table , which
 * will be new unless we were already at MAXIMUM _ CAPACITY . */
private SimpleHashSetEntry < T > [ ] doubleCapacity ( ) { } }

implementation:
SimpleHashSetEntry < T > [ ] oldTable = mTable ; int oldCapacity = oldTable . length ; if ( oldCapacity == MAXIMUM_CAPACITY ) { return oldTable ; } int newCapacity = oldCapacity * 2 ; SimpleHashSetEntry < T > [ ] newTable = makeTable ( newCapacity ) ; if ( mSize == 0 ) { return newTable ; } for ( int j = 0 ; j < oldCapacity ; j ++ ) { /* * Rehash the bucket using the minimum number of field writes .
 * This is the most subtle and delicate code in the class . */
SimpleHashSetEntry < T > e = oldTable [ j ] ; if ( e == null ) { continue ; } int highBit = e . mHash & oldCapacity ; SimpleHashSetEntry < T > broken = null ; newTable [ j | highBit ] = e ; for ( SimpleHashSetEntry < T > n = e . mNext ; n != null ; e = n , n = n . mNext ) { int nextHighBit = n . mHash & oldCapacity ; if ( nextHighBit != highBit ) { if ( broken == null ) { newTable [ j | nextHighBit ] = n ; } else { broken . mNext = n ; } broken = e ; highBit = nextHighBit ; } } if ( broken != null ) broken . mNext = null ; } return newTable ;


signature:
public class ImageDiskCacheProvider { /** * Adds a bitmap to both memory and disk cache
 * @ param key Unique identifier for the bitmap to store
 * @ param bitmap The bitmap to store */
public void write ( String key , Bitmap bitmap ) { } }

implementation:
if ( key == null || bitmap == null ) { return ; } // Add to disk cache
OutputStream out = null ; try { CacheEntry cacheEntry = mDiskCache . beginEdit ( key ) ; if ( cacheEntry != null ) { out = cacheEntry . newOutputStream ( ) ; bitmap . compress ( DEFAULT_COMPRESS_FORMAT , DEFAULT_COMPRESS_QUALITY , out ) ; cacheEntry . commit ( ) ; out . close ( ) ; } } catch ( final IOException e ) { CLog . e ( LOG_TAG , "addBitmapToCache - " + e ) ; } catch ( Exception e ) { CLog . e ( LOG_TAG , "addBitmapToCache - " + e ) ; } finally { try { if ( out != null ) { out . close ( ) ; } } catch ( IOException e ) { } }


signature:
public class CacheManagerFactory { /** * 10M */
public static CacheManager getDefault ( ) { } }

implementation: if ( sDefault == null ) { initDefaultCache ( Cube . getInstance ( ) . getContext ( ) , DEFAULT_CACHE_DIR , DEFAULT_CACHE_MEMORY_CACHE_SIZE , DEFAULT_CACHE_DISK_CACHE_SIZE ) ; } return sDefault ;


signature:
public class CacheEntry { /** * Returns the last committed value as a string , or null if no value
 * has been committed . */
public String getString ( ) throws IOException { } }

implementation: InputStream in = getInputStream ( ) ; return in != null ? inputStreamToString ( in ) : null ;


signature:
public class CacheEntry { /** * Sets the value */
public CacheEntry setString ( String value ) throws IOException { } }

implementation: Writer writer = null ; try { writer = new OutputStreamWriter ( newOutputStream ( ) , UTF_8 ) ; writer . write ( value ) ; } finally { FileUtils . closeQuietly ( writer ) ; } return this ;


signature:
public class CacheEntry { /** * Returns a new unbuffered output stream to write the value
 * If the underlying output stream encounters errors
 * when writing to the filesystem , this edit will be aborted when
 * { @ link # commit } is called . The returned output stream does not throw
 * IOExceptions . */
public OutputStream newOutputStream ( ) throws IOException { } }

implementation: synchronized ( mDiskCache ) { if ( mIsUnderEdit ) { throw new IOException ( "This file has been under edit" ) ; } mIsUnderEdit = true ; File tempFile = getTempFile ( ) ; File parent = tempFile . getParentFile ( ) ; if ( ! parent . exists ( ) && ! parent . mkdirs ( ) ) { throw new IOException ( "Can not make sure the parent directory exist." ) ; } return new FaultHidingOutputStream ( new FileOutputStream ( tempFile ) ) ; }


signature:
public class CacheEntry { /** * delete all content
 * @ return */
public boolean delete ( ) throws IOException { } }

implementation: if ( mIsUnderEdit ) { throw new IOException ( "Try to delete an cache entry that has been being editing." ) ; } FileUtils . deleteIfExists ( getCacheFile ( ) ) ; FileUtils . deleteIfExists ( getTempFile ( ) ) ; return true ;


signature:
public class CacheEntry { /** * Commits this edit so it is visible to readers . This releases the
 * edit lock so another edit may be started on the same key . */
public void commit ( ) throws IOException { } }

implementation: if ( ! mIsUnderEdit ) { throw new IOException ( "CacheEntry has been closed." ) ; } if ( hasErrors ) { mDiskCache . delete ( mKey ) ; } else { File dirty = getTempFile ( ) ; if ( dirty . exists ( ) ) { File clean = getCacheFile ( ) ; dirty . renameTo ( clean ) ; mOldSize = mSize ; mSize = clean . length ( ) ; mDiskCache . commitEdit ( this ) ; } else { abortEdit ( ) ; } } mIsUnderEdit = false ;


signature:
public class CacheEntry { /** * Aborts this edit . This releases the edit lock so another edit may be
 * started on the same mKey . */
public synchronized void abortEdit ( ) throws IOException { } }

implementation: if ( ! mIsUnderEdit ) { return ; } mIsUnderEdit = false ; FileUtils . deleteIfExists ( getTempFile ( ) ) ; mDiskCache . abortEdit ( this ) ;


signature:
public class RequestData { /** * add file to be uploaded
 * @ param fieldName
 * @ param uploadFile
 * @ param fileName if provided , will use this as filename
 * @ return */
@ SuppressWarnings ( { } }

implementation: "unused" } ) public RequestData addFile ( String fieldName , String uploadFile , String fileName ) { addFile ( fieldName , new File ( uploadFile ) , fileName ) ; return this ;


signature:
public class DefaultMemoryCache { /** * Get from memory cache . */
@ Override public BitmapDrawable get ( String key ) { } }

implementation: BitmapDrawable memValue = null ; if ( mMemoryCache != null ) { memValue = mMemoryCache . get ( key ) ; } return memValue ;


signature:
public class DefaultMemoryCache { /** * clear the memory cache */
@ Override public void clear ( ) { } }

implementation: if ( mMemoryCache != null ) { mMemoryCache . evictAll ( ) ; if ( DEBUG ) { Log . d ( LOG_TAG , "Memory cache cleared" ) ; } }


signature:
public class LruActionTracer { /** * try to resume last status when we got off
 * @ throws java . io . IOException */
public void tryToResume ( ) throws IOException { } }

implementation:
if ( mJournalFile . exists ( ) ) { try { readJournal ( ) ; processJournal ( ) ; mJournalWriter = new BufferedWriter ( new FileWriter ( mJournalFile , true ) , IO_BUFFER_SIZE ) ; if ( SimpleDiskLruCache . DEBUG ) { CLog . d ( SimpleDiskLruCache . LOG_TAG , "open success" ) ; } } catch ( IOException journalIsCorrupt ) { journalIsCorrupt . printStackTrace ( ) ; if ( SimpleDiskLruCache . DEBUG ) { CLog . d ( SimpleDiskLruCache . LOG_TAG , "clear old cache" ) ; } clear ( ) ; } } else { if ( SimpleDiskLruCache . DEBUG ) { CLog . d ( SimpleDiskLruCache . LOG_TAG , "create new cache" ) ; } // create a new empty cache
if ( mDirectory . exists ( ) ) { mDirectory . delete ( ) ; } mDirectory . mkdirs ( ) ; rebuildJournal ( ) ; }


signature:
public class LruActionTracer { /** * Returns a { @ link in . srain . cube . diskcache . CacheEntry } named { @ code key } , or null if it doesn ' t
 * exist is not currently readable . If a value is returned , it is moved to
 * the head of the LRU queue . */
public synchronized CacheEntry getEntry ( String key ) throws IOException { } }

implementation: checkNotClosed ( ) ; validateKey ( key ) ; CacheEntry cacheEntry = mLruEntries . get ( key ) ; if ( cacheEntry == null ) { return null ; } trimToSize ( ) ; addActionLog ( ACTION_READ , cacheEntry ) ; return cacheEntry ;


signature:
public class LruActionTracer { /** * Computes the initial size and collects garbage as a part of opening the
 * cache . Dirty entries are assumed to be inconsistent and will be deleted . */
private void processJournal ( ) throws IOException { } }

implementation: FileUtils . deleteIfExists ( mJournalFileTmp ) ; for ( Iterator < CacheEntry > i = mLruEntries . values ( ) . iterator ( ) ; i . hasNext ( ) ; ) { CacheEntry cacheEntry = i . next ( ) ; if ( ! cacheEntry . isUnderEdit ( ) ) { mSize += cacheEntry . getSize ( ) ; } else { cacheEntry . delete ( ) ; i . remove ( ) ; } }


signature:
public class LruActionTracer { /** * Creates a new journal that omits redundant information . This replaces the
 * current journal if it exists . */
private void rebuildJournal ( ) throws IOException { } }

implementation: if ( mJournalWriter != null ) { mJournalWriter . close ( ) ; } Writer writer = new BufferedWriter ( new FileWriter ( mJournalFileTmp ) , IO_BUFFER_SIZE ) ; writer . write ( MAGIC ) ; writer . write ( "\n" ) ; writer . write ( VERSION_1 ) ; writer . write ( "\n" ) ; writer . write ( Integer . toString ( mAppVersion ) ) ; writer . write ( "\n" ) ; writer . write ( "\n" ) ; for ( CacheEntry cacheEntry : mLruEntries . values ( ) ) { if ( cacheEntry . isUnderEdit ( ) ) { writer . write ( sACTION_LIST [ ACTION_DIRTY ] + ' ' + cacheEntry . getKey ( ) + " " + cacheEntry . getSize ( ) + '\n' ) ; } else { writer . write ( sACTION_LIST [ ACTION_CLEAN ] + ' ' + cacheEntry . getKey ( ) + " " + cacheEntry . getSize ( ) + '\n' ) ; } } writer . close ( ) ; mJournalFileTmp . renameTo ( mJournalFile ) ; mJournalWriter = new BufferedWriter ( new FileWriter ( mJournalFile , true ) , IO_BUFFER_SIZE ) ;


signature:
public class LruActionTracer { /** * remove files from list , delete files */
private synchronized void trimToSize ( ) { } }

implementation: if ( mSize > mCapacity ) { if ( SimpleDiskLruCache . DEBUG ) { CLog . d ( SimpleDiskLruCache . LOG_TAG , "should trim, current is: %s" , mSize ) ; } } while ( mSize > mCapacity ) { Map . Entry < String , CacheEntry > toEvict = mLruEntries . entrySet ( ) . iterator ( ) . next ( ) ; String key = toEvict . getKey ( ) ; CacheEntry cacheEntry = toEvict . getValue ( ) ; mLruEntries . remove ( key ) ; mSize -= cacheEntry . getSize ( ) ; addActionLog ( ACTION_PENDING_DELETE , cacheEntry ) ; if ( SimpleDiskLruCache . DEBUG ) { CLog . d ( SimpleDiskLruCache . LOG_TAG , "pending remove: %s, size: %s, after remove total: %s" , key , cacheEntry . getSize ( ) , mSize ) ; } }


signature:
public class CubeFragmentActivity { /** * process back pressed */
@ Override public void onBackPressed ( ) { } }

implementation:
// process back for fragment
if ( processBackPressed ( ) ) { return ; } // process back for fragment
boolean enableBackPressed = true ; if ( mCurrentFragment != null ) { enableBackPressed = ! mCurrentFragment . processBackPressed ( ) ; } if ( enableBackPressed ) { int cnt = getSupportFragmentManager ( ) . getBackStackEntryCount ( ) ; if ( cnt <= 1 && isTaskRoot ( ) ) { String closeWarningHint = getCloseWarning ( ) ; if ( ! mCloseWarned && ! TextUtils . isEmpty ( closeWarningHint ) ) { Toast toast = Toast . makeText ( this , closeWarningHint , Toast . LENGTH_SHORT ) ; toast . show ( ) ; mCloseWarned = true ; } else { doReturnBack ( ) ; } } else { mCloseWarned = false ; doReturnBack ( ) ; } }


signature:
public class LoadMoreContainerBase { /** * page has loaded
 * @ param emptyResult
 * @ param hasMore */
@ Override public void loadMoreFinish ( boolean emptyResult , boolean hasMore ) { } }

implementation: mLoadError = false ; mListEmpty = emptyResult ; mIsLoading = false ; mHasMore = hasMore ; if ( mLoadMoreUIHandler != null ) { mLoadMoreUIHandler . onLoadFinish ( this , emptyResult , hasMore ) ; }


signature:
public class ImageReuseInfoManger { /** * Find out the size list can be re - sued .
 * @ param thisSize if " small _ 180 " is input
 * @ return { " big _ 360 " , " big _ 720 " } will be returned . */
public ImageReuseInfo create ( String thisSize ) { } }

implementation: ArrayList < String > list = new ArrayList < String > ( ) ; boolean canBeReused = false ; for ( int i = 0 ; i < mSizeList . length ; i ++ ) { String size = mSizeList [ i ] ; if ( ! canBeReused && thisSize . equals ( size ) ) { canBeReused = true ; continue ; } if ( canBeReused && ! thisSize . equals ( size ) ) { list . add ( size ) ; } } if ( list . size ( ) == 0 ) { return new ImageReuseInfo ( thisSize , null ) ; } else { String [ ] sizeList = new String [ list . size ( ) ] ; list . toArray ( sizeList ) ; return new ImageReuseInfo ( thisSize , sizeList ) ; }


signature:
public class CacheAbleRequest { /** * Timeout will not be considerate
 * @ return */
@ Override protected T doRequestSync ( ) { } }

implementation: T data = RequestCacheManager . getInstance ( ) . requestCacheSync ( this ) ; if ( data == null ) { data = RequestManager . getInstance ( ) . getRequestProxy ( this ) . requestSync ( this ) ; } return data ;


signature: public class CacheAbleRequest { @ Override public void onCacheData ( CacheResultType cacheResultType , T data , boolean outOfDate ) { } }

implementation: if ( DEBUG ) { CLog . d ( LOG_TAG , "%s, onQueryFinish, out of date: %s" , getCacheKey ( ) , outOfDate ) ; } if ( hasBeenCanceled ( ) ) { return ; } mCacheData = data ; mOutOfDate = outOfDate ; if ( mHandler != null ) { mHandler . onCacheData ( data , outOfDate ) ; if ( mUseCacheAnyway ) { notifyRequestFinish ( ResultType . USE_CACHE_ANYWAY , data , mOutOfDate ) ; } else { if ( ! outOfDate ) { notifyRequestFinish ( ResultType . USE_CACHE_NOT_EXPIRED , data , false ) ; } } }


signature:
public class CacheAbleRequest { /** * will only notify once
 * @ param type
 * @ param outOfDate */
private void notifyRequestFinish ( ResultType type , T cacheData , boolean outOfDate ) { } }

implementation: if ( DEBUG ) { CLog . d ( LOG_TAG , "%s, notifyRequestFinish: %s, %s" , getCacheKey ( ) , type , outOfDate ) ; } if ( mHasNotified ) { return ; } mHasNotified = true ; mHandler . onCacheAbleRequestFinish ( cacheData , type , outOfDate ) ;


signature:
public class DefaultImageReSizer { /** * Calculate an inSampleSize for use in a { @ link BitmapFactory . Options } object when decoding bitmaps using the decode * methods from { @ link BitmapFactory } .
 * This implementation calculates the closest inSampleSize that is a times of 2 and will result in the final decoded bitmap having a width and height equal to or larger than the requested width and height . */
public static int calculateInSampleSize ( int originWidth , int originHeight , int reqWidth , int reqHeight ) { } }

implementation:
int inSampleSize = 1 ; if ( reqHeight <= 0 || reqHeight <= 0 || reqHeight == Integer . MAX_VALUE || reqWidth == Integer . MAX_VALUE ) { return inSampleSize ; } if ( originWidth > reqHeight || originHeight > reqWidth ) { final int halfHeight = originWidth / 2 ; final int halfWidth = originHeight / 2 ; // Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width .
while ( ( halfHeight / inSampleSize ) > reqHeight && ( halfWidth / inSampleSize ) > reqWidth ) { inSampleSize *= 2 ; } } return inSampleSize ;


signature:
public class Encrypt { /** * A hashing method that changes a string ( like a URL ) into a hash string */
public static String md5 ( String key ) { } }

implementation: String cacheKey ; try { final MessageDigest mDigest = MessageDigest . getInstance ( "MD5" ) ; mDigest . update ( key . getBytes ( ) ) ; cacheKey = bytesToHexString ( mDigest . digest ( ) ) ; } catch ( NoSuchAlgorithmException e ) { cacheKey = String . valueOf ( key . hashCode ( ) ) ; } return cacheKey ;


signature:
public class BaseRequestSender { /** * Completes the request and receives response from the server .
 * @ return a list of Strings as response in case the server returned
 * status OK , otherwise an exception is thrown .
 * @ throws IOException */
public void getResponse ( StringBuilder sb ) throws IOException { } }

implementation:
// checks server ' s status code first
int status = mHttpURLConnection . getResponseCode ( ) ; if ( status == HttpURLConnection . HTTP_OK ) { InputStream ips = new BufferedInputStream ( mHttpURLConnection . getInputStream ( ) ) ; BufferedReader reader = new BufferedReader ( new InputStreamReader ( ips , "UTF-8" ) ) ; char [ ] buffer = new char [ 1024 ] ; int bufferLength ; while ( ( bufferLength = reader . read ( buffer , 0 , buffer . length ) ) > 0 ) { sb . append ( buffer , 0 , bufferLength ) ; } reader . close ( ) ; ips . close ( ) ; mHttpURLConnection . disconnect ( ) ; } else { throw new IOException ( "Server returned non-OK status: " + status ) ; }


signature:
public class DefaultImageLoadHandler { /** * set the placeholder bitmap */
public void setLoadingBitmap ( Bitmap loadingBitmap ) { } }

implementation: if ( Version . hasHoneycomb ( ) ) { mLoadingDrawable = new BitmapDrawable ( mContext . getResources ( ) , loadingBitmap ) ; }


signature:
public class TitleHeaderBar { /** * set customized view to left side
 * @ param view the view to be added to left side */
public void setCustomizedLeftView ( View view ) { } }

implementation: mLeftReturnImageView . setVisibility ( GONE ) ; RelativeLayout . LayoutParams lp = makeLayoutParams ( view ) ; lp . addRule ( CENTER_VERTICAL ) ; lp . addRule ( ALIGN_PARENT_LEFT ) ; getLeftViewContainer ( ) . addView ( view , lp ) ;


signature:
public class TitleHeaderBar { /** * set customized view to left side
 * @ param layoutId the xml layout file id */
public void setCustomizedLeftView ( int layoutId ) { } }

implementation: View view = inflate ( getContext ( ) , layoutId , null ) ; setCustomizedLeftView ( view ) ;


signature:
public class TitleHeaderBar { /** * set customized view to center
 * @ param view the view to be added to center */
public void setCustomizedCenterView ( View view ) { } }

implementation: mCenterTitleTextView . setVisibility ( GONE ) ; RelativeLayout . LayoutParams lp = makeLayoutParams ( view ) ; lp . addRule ( CENTER_IN_PARENT ) ; getCenterViewContainer ( ) . addView ( view , lp ) ;


signature:
public class TitleHeaderBar { /** * set customized view to center
 * @ param layoutId the xml layout file id */
public void setCustomizedCenterView ( int layoutId ) { } }

implementation: View view = inflate ( getContext ( ) , layoutId , null ) ; setCustomizedCenterView ( view ) ;


signature:
public class TitleHeaderBar { /** * set customized view to right side
 * @ param view the view to be added to right side */
public void setCustomizedRightView ( View view ) { } }

implementation: RelativeLayout . LayoutParams lp = makeLayoutParams ( view ) ; lp . addRule ( CENTER_VERTICAL ) ; lp . addRule ( ALIGN_PARENT_RIGHT ) ; getRightViewContainer ( ) . addView ( view , lp ) ;


signature:
public class SimpleDownloader { /** * Download a bitmap from a URL and write the content to an output stream . */
public boolean downloadToStream ( ImageTask imageTask , String urlString , OutputStream outputStream , ProgressUpdateHandler progressUpdateHandler ) { } }

implementation: disableConnectionReuseIfNecessary ( ) ; HttpURLConnection urlConnection = null ; BufferedOutputStream out = null ; BufferedInputStream in = null ; try { final URL url = new URL ( urlString ) ; urlConnection = ( HttpURLConnection ) url . openConnection ( ) ; urlConnection . setReadTimeout ( 0 ) ; int len = urlConnection . getContentLength ( ) ; int total = 0 ; in = new BufferedInputStream ( urlConnection . getInputStream ( ) , IO_BUFFER_SIZE ) ; out = new BufferedOutputStream ( outputStream , IO_BUFFER_SIZE ) ; int b ; while ( ( b = in . read ( ) ) != - 1 ) { total ++ ; out . write ( b ) ; if ( progressUpdateHandler != null ) { progressUpdateHandler . onProgressUpdate ( total , len ) ; } } return true ; } catch ( final IOException e ) { CLog . e ( LOG_TAG , "Error in downloadBitmap - " + e ) ; } finally { if ( urlConnection != null ) { urlConnection . disconnect ( ) ; } try { if ( out != null ) { out . close ( ) ; } if ( in != null ) { in . close ( ) ; } } catch ( final IOException e ) { } } return false ;


signature:
public class ImageTask { /** * Generate the identity key .
 * This key should be related to the unique image this task is requesting : the size , the remote url .
 * @ return */
protected String generateIdentityKey ( ) { } }

implementation: if ( mRequest . getImageReuseInfo ( ) == null ) { return getIdentityUrl ( ) ; } else { return joinSizeTagToKey ( getIdentityUrl ( ) , mRequest . getImageReuseInfo ( ) . getIdentitySize ( ) ) ; }


signature:
public class ImageTask { /** * Check the given { @ link in . srain . cube . image . ImageLoadRequest } is loading .
 * @ param request
 * @ return Identify the given url , if same to { @ link # mIdentityUrl } return true . */
public boolean isLoadingThisUrl ( ImageLoadRequest request ) { } }

implementation: String url2 = ImageLoaderFactory . getNameGenerator ( ) . generateIdentityUrlFor ( request ) ; return getIdentityUrl ( ) . equals ( url2 ) ;


signature:
public class ImageTask { /** * Bind ImageView with ImageTask
 * @ param imageView */
public void addImageView ( CubeImageView imageView ) { } }

implementation: if ( null == imageView ) { return ; } if ( null == mFirstImageViewHolder ) { mFirstImageViewHolder = new ImageViewHolder ( imageView ) ; return ; } ImageViewHolder holder = mFirstImageViewHolder ; for ( ; ; holder = holder . mNext ) { if ( holder . contains ( imageView ) ) { return ; } if ( holder . mNext == null ) { break ; } } ImageViewHolder newHolder = new ImageViewHolder ( imageView ) ; newHolder . mPrev = holder ; holder . mNext = newHolder ;


signature:
public class ImageTask { /** * Remove the ImageView from ImageTask
 * @ param imageView */
public void removeImageView ( CubeImageView imageView ) { } }

implementation:
if ( null == imageView || null == mFirstImageViewHolder ) { return ; } ImageViewHolder holder = mFirstImageViewHolder ; do { if ( holder . contains ( imageView ) ) { // Make sure entry is right .
if ( holder == mFirstImageViewHolder ) { mFirstImageViewHolder = holder . mNext ; } if ( null != holder . mNext ) { holder . mNext . mPrev = holder . mPrev ; } if ( null != holder . mPrev ) { holder . mPrev . mNext = holder . mNext ; } } } while ( ( holder = holder . mNext ) != null ) ;


signature:
public class ImageTask { /** * When loading from network
 * @ param handler */
public void onLoading ( ImageLoadHandler handler ) { } }

implementation: mFlag = mFlag | STATUS_LOADING ; if ( null == handler ) { return ; } if ( mFirstImageViewHolder == null ) { handler . onLoading ( this , null ) ; } else { ImageViewHolder holder = mFirstImageViewHolder ; do { final CubeImageView imageView = holder . getImageView ( ) ; if ( null != imageView ) { handler . onLoading ( this , imageView ) ; } } while ( ( holder = holder . mNext ) != null ) ; }


signature:
public class ImageTask { /** * notify loading
 * @ param handler
 * @ param imageView */
public void notifyLoading ( ImageLoadHandler handler , CubeImageView imageView ) { } }

implementation: if ( handler == null || imageView == null ) { return ; } handler . onLoading ( this , imageView ) ;


signature:
public class ImageTask { /** * Will be called when begin load image data from dish or network
 * @ param drawable */
public void onLoadTaskFinish ( BitmapDrawable drawable , ImageLoadHandler handler ) { } }

implementation: mFlag &= ~ STATUS_LOADING ; if ( null == handler ) { return ; } int errorCode = mFlag & ERROR_CODE_MASK ; if ( errorCode > 0 ) { onLoadError ( errorCode , handler ) ; return ; } if ( null != mImageTaskStatistics ) { mImageTaskStatistics . s5_beforeShow ( ) ; } if ( mFirstImageViewHolder == null ) { handler . onLoadFinish ( this , null , drawable ) ; } else { ImageViewHolder holder = mFirstImageViewHolder ; do { final CubeImageView imageView = holder . getImageView ( ) ; if ( null != imageView ) { imageView . onLoadFinish ( ) ; handler . onLoadFinish ( this , imageView , drawable ) ; } } while ( ( holder = holder . mNext ) != null ) ; } if ( null != mImageTaskStatistics ) { mImageTaskStatistics . s6_afterShow ( ImageProvider . getBitmapSize ( drawable ) ) ; ImagePerformanceStatistics . onImageLoaded ( this , mImageTaskStatistics ) ; }


signature:
public class ImageTask { /** * Join the key and the size information .
 * @ param key
 * @ param w
 * @ param h
 * @ return " $ key " + " _ " + " $ w " + " _ " + " $ h " */
public static String joinSizeInfoToKey ( String key , int w , int h ) { } }

implementation: if ( w > 0 && h != Integer . MAX_VALUE && h > 0 && h != Integer . MAX_VALUE ) { return new StringBuilder ( key ) . append ( SIZE_SP ) . append ( w ) . append ( SIZE_SP ) . append ( h ) . toString ( ) ; } return key ;


signature:
public class ImageTask { /** * Join the tag with the key .
 * @ param key
 * @ param tag
 * @ return " $ key " + " _ " + " $ tag " */
public static String joinSizeTagToKey ( String key , String tag ) { } }

implementation: return new StringBuilder ( key ) . append ( SIZE_SP ) . append ( tag ) . toString ( ) ;


signature:
public class DiskCacheProvider { /** * initiate the disk cache */
public void openDiskCacheAsync ( ) { } }

implementation: if ( DEBUG ) { CLog . d ( LOG_TAG , "%s: initDiskCacheAsync" , mDiskCache ) ; } synchronized ( mDiskCacheLock ) { mDiskCacheStarting = true ; new FileCacheTask ( TASK_INIT_CACHE ) . executeNow ( ) ; }


signature:
public class DiskCacheProvider { /** * flush the data to disk cache */
public void flushDiskCacheAsyncWithDelay ( int delay ) { } }

implementation: if ( DEBUG ) { CLog . d ( LOG_TAG , "%s, flushDiskCacheAsyncWithDelay" , delay ) ; } if ( mIsDelayFlushing ) { return ; } mIsDelayFlushing = true ; new FileCacheTask ( TASK_FLUSH_CACHE ) . executeAfter ( delay ) ;


signature:
public class DiskCacheProvider { /** * If disk is not read , will prepare it first .
 * @ return */
public DiskCache getDiskCache ( ) { } }

implementation: if ( ! mDiskCacheReady ) { if ( DEBUG ) { CLog . d ( LOG_TAG , "%s, try to access disk cache, but it is not open, try to open it." , mDiskCache ) ; } openDiskCacheAsync ( ) ; } synchronized ( mDiskCacheLock ) { while ( mDiskCacheStarting ) { try { if ( DEBUG ) { CLog . d ( LOG_TAG , "%s, try to access, but disk cache is not ready, wait" , mDiskCache ) ; } mDiskCacheLock . wait ( ) ; } catch ( InterruptedException e ) { } } } return mDiskCache ;


signature:
public class FileUtils { /** * Try to delete directory in a fast way . */
public static void deleteDirectoryQuickly ( File dir ) throws IOException { } }

implementation:
if ( ! dir . exists ( ) ) { return ; } final File to = new File ( dir . getAbsolutePath ( ) + System . currentTimeMillis ( ) ) ; dir . renameTo ( to ) ; if ( ! dir . exists ( ) ) { // rebuild
dir . mkdirs ( ) ; } // try to run " rm - r " to remove the whole directory
if ( to . exists ( ) ) { String deleteCmd = "rm -r " + to ; Runtime runtime = Runtime . getRuntime ( ) ; try { Process process = runtime . exec ( deleteCmd ) ; process . waitFor ( ) ; } catch ( IOException e ) { } catch ( InterruptedException e ) { e . printStackTrace ( ) ; } } if ( ! to . exists ( ) ) { return ; } deleteDirectoryRecursively ( to ) ; if ( to . exists ( ) ) { to . delete ( ) ; }


signature:
public class FileUtils { /** * recursively delete
 * @ param dir
 * @ throws java . io . IOException */
public static void deleteDirectoryRecursively ( File dir ) throws IOException { } }

implementation: File [ ] files = dir . listFiles ( ) ; if ( files == null ) { throw new IllegalArgumentException ( "not a directory: " + dir ) ; } for ( File file : files ) { if ( file . isDirectory ( ) ) { deleteDirectoryRecursively ( file ) ; } if ( ! file . delete ( ) ) { throw new IOException ( "failed to delete file: " + file ) ; } }


signature:
public class DiskFileUtils { /** * Get a usable cache directory ( external if available , internal otherwise ) .
 * Check if media is mounted or storage is built - in , if so , try and use external cache folder
 * otherwise use internal cache folder
 * If both of them can not meet the requirement , use the bigger one .
 * @ param context The context to use
 * @ param uniqueName A unique folder name to append to the cache folder
 * @ return The cache folder */
public static CacheDirInfo getDiskCacheDir ( Context context , String uniqueName , long requireSpace ) { } }

implementation:
File sdPath = null ; File internalPath = null ; Long sdCardFree = 0L ; boolean usingInternal = false ; if ( hasSDCardMounted ( ) ) { sdPath = getExternalCacheDir ( context ) ; if ( ! sdPath . exists ( ) ) { sdPath . mkdirs ( ) ; } sdCardFree = getUsableSpace ( sdPath ) ; } CacheDirInfo cacheDirInfo = new CacheDirInfo ( ) ; cacheDirInfo . requireSize = requireSpace ; // sd card can not meet the requirement
// try to use the build - in storage
if ( sdPath == null || sdCardFree < requireSpace ) { internalPath = context . getCacheDir ( ) ; long internalFree = getUsableSpace ( internalPath ) ; // both lower then requirement , choose the bigger one
if ( internalFree < requireSpace ) { if ( internalFree > sdCardFree ) { usingInternal = true ; cacheDirInfo . realSize = internalFree ; } else { usingInternal = false ; cacheDirInfo . realSize = sdCardFree ; } cacheDirInfo . isNotEnough = true ; } else { usingInternal = true ; cacheDirInfo . realSize = requireSpace ; } } else { usingInternal = false ; cacheDirInfo . realSize = requireSpace ; } cacheDirInfo . isInternal = usingInternal ; if ( usingInternal ) { cacheDirInfo . path = new File ( internalPath . getPath ( ) + File . separator + uniqueName ) ; } else { cacheDirInfo . path = new File ( sdPath . getPath ( ) + File . separator + uniqueName ) ; } if ( ! cacheDirInfo . path . exists ( ) && ! cacheDirInfo . path . mkdirs ( ) ) { CLog . e ( "cube-cache" , "can not create directory for: %s" , cacheDirInfo . path ) ; } return cacheDirInfo ;


signature:
public class DiskFileUtils { /** * Get the external application cache directory .
 * @ param context The context to use
 * @ return The external cache folder : / storage / sdcard0 / Android / data / com . srain . sdk / cache */
@ TargetApi ( Build . VERSION_CODES . FROYO ) public static File getExternalCacheDir ( Context context ) { } }

implementation:
if ( Version . hasFroyo ( ) ) { File path = context . getExternalCacheDir ( ) ; // In some case , even the sd card is mounted , getExternalCacheDir will return null , may be it is nearly full .
if ( path != null ) { return path ; } } // Before Froyo or the path is null , we need to construct the external cache folder ourselves
final String cacheDir = "/Android/data/" + context . getPackageName ( ) + "/cache/" ; return new File ( Environment . getExternalStorageDirectory ( ) . getPath ( ) + cacheDir ) ;


signature:
public class DiskFileUtils { /** * Check how much usable space is available at a given path .
 * @ param path The path to check
 * @ return The space available in bytes by user , not by root , - 1 means path is null , 0 means path is not exist . */
@ SuppressWarnings ( "deprecation" ) @ TargetApi ( Build . VERSION_CODES . GINGERBREAD ) public static long getUsableSpace ( File path ) { } }

implementation: if ( path == null ) { return - 1 ; } if ( Version . hasGingerbread ( ) ) { return path . getUsableSpace ( ) ; } else { if ( ! path . exists ( ) ) { return 0 ; } else { final StatFs stats = new StatFs ( path . getPath ( ) ) ; return ( long ) stats . getBlockSize ( ) * ( long ) stats . getAvailableBlocks ( ) ; } }


signature:
public class DiskFileUtils { /** * external : " / storage / emulated / 0 / Android / data / in . srain . sample / files "
 * internal : " / data / data / in . srain . sample / files " */
public static String wantFilesPath ( Context context , boolean externalStorageFirst ) { } }

implementation: String path = null ; File f = null ; if ( externalStorageFirst && DiskFileUtils . hasSDCardMounted ( ) && ( f = context . getExternalFilesDir ( "xxx" ) ) != null ) { path = f . getAbsolutePath ( ) ; } else { path = context . getFilesDir ( ) . getAbsolutePath ( ) ; } return path ;


signature:
public class CubeImageView { /** * Notifies the drawable that it ' s displayed state has changed .
 * @ param drawable
 * @ param isDisplayed */
private static void notifyDrawable ( Drawable drawable , final boolean isDisplayed ) { } }

implementation:
if ( drawable instanceof RecyclingBitmapDrawable ) { // The drawable is a CountingBitmapDrawable , so notify it
( ( RecyclingBitmapDrawable ) drawable ) . setIsDisplayed ( isDisplayed ) ; } else if ( drawable instanceof LayerDrawable ) { // The drawable is a LayerDrawable , so recurse on each layer
LayerDrawable layerDrawable = ( LayerDrawable ) drawable ; for ( int i = 0 , z = layerDrawable . getNumberOfLayers ( ) ; i < z ; i ++ ) { notifyDrawable ( layerDrawable . getDrawable ( i ) , isDisplayed ) ; } }


signature:
public class CubeFragment { /** * Only when Activity resume , not very precise .
 * When activity recover from partly invisible , onBecomesPartiallyInvisible will be triggered . */
@ Override public void onResume ( ) { } }

implementation: super . onResume ( ) ; if ( ! mFirstResume ) { onBack ( ) ; } if ( mFirstResume ) { mFirstResume = false ; } if ( DEBUG ) { showStatus ( "onResume" ) ; }


signature:
public class ListPageInfo { /** * the last item in list
 * @ return */
public T lastItem ( ) { } }

implementation: if ( mDataList == null || mDataList . size ( ) == 0 ) { return null ; } return mDataList . get ( mDataList . size ( ) - 1 ) ;


signature:
public class Fab { /** * Shows the FAB and sets the FAB ' s translation .
 * @ param translationX translation X value
 * @ param translationY translation Y value */
@ Override public void show ( float translationX , float translationY ) { } }

implementation:
// Set FAB ' s translation
setTranslation ( translationX , translationY ) ; // Only use scale animation if FAB is hidden
if ( getVisibility ( ) != View . VISIBLE ) { // Pivots indicate where the animation begins from
float pivotX = getPivotX ( ) + translationX ; float pivotY = getPivotY ( ) + translationY ; ScaleAnimation anim ; // If pivots are 0 , that means the FAB hasn ' t been drawn yet so just use the
// center of the FAB
if ( pivotX == 0 || pivotY == 0 ) { anim = new ScaleAnimation ( 0 , 1 , 0 , 1 , Animation . RELATIVE_TO_SELF , 0.5f , Animation . RELATIVE_TO_SELF , 0.5f ) ; } else { anim = new ScaleAnimation ( 0 , 1 , 0 , 1 , pivotX , pivotY ) ; } // Animate FAB expanding
anim . setDuration ( FAB_ANIM_DURATION ) ; anim . setInterpolator ( getInterpolator ( ) ) ; startAnimation ( anim ) ; } setVisibility ( View . VISIBLE ) ;


signature:
public class Fab { /** * Hides the FAB . */
@ Override public void hide ( ) { } }

implementation:
// Only use scale animation if FAB is visible
if ( getVisibility ( ) == View . VISIBLE ) { // Pivots indicate where the animation begins from
float pivotX = getPivotX ( ) + getTranslationX ( ) ; float pivotY = getPivotY ( ) + getTranslationY ( ) ; // Animate FAB shrinking
ScaleAnimation anim = new ScaleAnimation ( 1 , 0 , 1 , 0 , pivotX , pivotY ) ; anim . setDuration ( FAB_ANIM_DURATION ) ; anim . setInterpolator ( getInterpolator ( ) ) ; startAnimation ( anim ) ; } setVisibility ( View . INVISIBLE ) ;


signature:
public class ViewAnimationUtils { /** * Returns an Animator which can animate a clipping circle .
 * Any shadow cast by the View will respect the circular clip from this animator .
 * Only a single non - rectangular clip can be applied on a View at any time .
 * Views clipped by a circular reveal animation take priority over
 * { @ link android . view . View # setClipToOutline ( boolean ) View Outline clipping } .
 * Note that the animation returned here is a one - shot animation . It cannot
 * be re - used , and once started it cannot be paused or resumed .
 * @ param view The View will be clipped to the animating circle .
 * @ param centerX The x coordinate of the center of the animating circle .
 * @ param centerY The y coordinate of the center of the animating circle .
 * @ param startRadius The starting radius of the animating circle .
 * @ param endRadius The ending radius of the animating circle . */
@ TargetApi ( Build . VERSION_CODES . LOLLIPOP ) public static SupportAnimator createCircularReveal ( View view , int centerX , int centerY , float startRadius , float endRadius ) { } }

implementation: if ( ! ( view . getParent ( ) instanceof RevealAnimator ) ) { throw new IllegalArgumentException ( "View must be inside RevealFrameLayout or RevealLinearLayout." ) ; } RevealAnimator revealLayout = ( RevealAnimator ) view . getParent ( ) ; revealLayout . attachRevealInfo ( new RevealInfo ( centerX , centerY , startRadius , endRadius , new WeakReference < > ( view ) ) ) ; if ( LOLLIPOP_PLUS ) { return new SupportAnimatorLollipop ( android . view . ViewAnimationUtils . createCircularReveal ( view , centerX , centerY , startRadius , endRadius ) , revealLayout ) ; } ObjectAnimator reveal = ObjectAnimator . ofFloat ( revealLayout , CLIP_RADIUS , startRadius , endRadius ) ; reveal . addListener ( getRevealFinishListener ( revealLayout ) ) ; return new SupportAnimatorPreL ( reveal , revealLayout ) ;


signature:
public class ViewAnimationUtils { /** * Lifting view
 * @ param view The animation target
 * @ param baseRotation initial Rotation X in 3D space
 * @ param fromY initial Y position of view
 * @ param duration aniamtion duration
 * @ param startDelay start delay before animation begin */
@ Deprecated public static void liftingFromBottom ( View view , float baseRotation , float fromY , int duration , int startDelay ) { } }

implementation: ViewHelper . setRotationX ( view , baseRotation ) ; ViewHelper . setTranslationY ( view , fromY ) ; ViewPropertyAnimator . animate ( view ) . setInterpolator ( new AccelerateDecelerateInterpolator ( ) ) . setDuration ( duration ) . setStartDelay ( startDelay ) . rotationX ( 0 ) . translationY ( 0 ) . start ( ) ;


signature:
public class MaterialSheetAnimation { /** * Aligns the sheet ' s position with the FAB .
 * @ param fab Floating action button */
public void alignSheetWithFab ( View fab ) { } }

implementation:
// NOTE : View . getLocationOnScreen ( ) returns the view ' s coordinates on the screen
// whereas other view methods like getRight ( ) and getY ( ) return coordinates relative
// to the view ' s parent . Using those methods can lead to incorrect calculations when
// the two views do not have the same parent .
// Get FAB ' s coordinates
int [ ] fabCoords = new int [ 2 ] ; fab . getLocationOnScreen ( fabCoords ) ; // Get sheet ' s coordinates
int [ ] sheetCoords = new int [ 2 ] ; sheet . getLocationOnScreen ( sheetCoords ) ; // NOTE : Use the diffs between the positions of the FAB and sheet to align the sheet .
// We have to use the diffs because the coordinates returned by getLocationOnScreen ( )
// include the status bar and any other system UI elements , meaning the coordinates
// aren ' t representative of the usable screen space .
int leftDiff = sheetCoords [ 0 ] - fabCoords [ 0 ] ; int rightDiff = ( sheetCoords [ 0 ] + sheet . getWidth ( ) ) - ( fabCoords [ 0 ] + fab . getWidth ( ) ) ; int topDiff = sheetCoords [ 1 ] - fabCoords [ 1 ] ; int bottomDiff = ( sheetCoords [ 1 ] + sheet . getHeight ( ) ) - ( fabCoords [ 1 ] + fab . getHeight ( ) ) ; // NOTE : Preserve the sheet ' s margins to allow users to shift the sheet ' s position
// to compensate for the fact that the design support library ' s FAB has extra
// padding within the view
ViewGroup . MarginLayoutParams sheetLayoutParams = ( ViewGroup . MarginLayoutParams ) sheet . getLayoutParams ( ) ; // Set sheet ' s new coordinates ( only if there is a change in coordinates because
// setting the same coordinates can cause the view to " drift " - moving 0.5 to 1 pixels
// around the screen )
if ( rightDiff != 0 ) { float sheetX = sheet . getX ( ) ; // Align the right side of the sheet with the right side of the FAB if
// doing so would not move the sheet off the screen
if ( rightDiff <= sheetX ) { sheet . setX ( sheetX - rightDiff - sheetLayoutParams . rightMargin ) ; revealXDirection = RevealXDirection . LEFT ; } // Otherwise , align the left side of the sheet with the left side of the FAB
else if ( leftDiff != 0 && leftDiff <= sheetX ) { sheet . setX ( sheetX - leftDiff + sheetLayoutParams . leftMargin ) ; revealXDirection = RevealXDirection . RIGHT ; } } if ( bottomDiff != 0 ) { float sheetY = sheet . getY ( ) ; // Align the bottom of the sheet with the bottom of the FAB
if ( bottomDiff <= sheetY ) { sheet . setY ( sheetY - bottomDiff - sheetLayoutParams . bottomMargin ) ; revealYDirection = RevealYDirection . UP ; } // Otherwise , align the top of the sheet with the top of the FAB
else if ( topDiff != 0 && topDiff <= sheetY ) { sheet . setY ( sheetY - topDiff + sheetLayoutParams . topMargin ) ; revealYDirection = RevealYDirection . DOWN ; } }


signature:
public class MaterialSheetAnimation { /** * Shows the sheet by morphing the FAB into the sheet .
 * @ param fab Floating action button
 * @ param showSheetDuration Duration of the sheet animation in milliseconds . Use 0 for no
 * animation .
 * @ param showSheetColorDuration Duration of the color animation in milliseconds . Use 0 for no
 * animation .
 * @ param listener Listener for animation events . */
public void morphFromFab ( View fab , long showSheetDuration , long showSheetColorDuration , AnimationListener listener ) { } }

implementation: sheet . setVisibility ( View . VISIBLE ) ; revealSheetWithFab ( fab , getFabRevealRadius ( fab ) , getSheetRevealRadius ( ) , showSheetDuration , fabColor , sheetColor , showSheetColorDuration , listener ) ;


signature:
public class MaterialSheetAnimation { /** * Hides the sheet by morphing the sheet into the FAB .
 * @ param fab Floating action button
 * @ param hideSheetDuration Duration of the sheet animation in milliseconds . Use 0 for no
 * animation .
 * @ param hideSheetColorDuration Duration of the color animation in milliseconds . Use 0 for no
 * animation .
 * @ param listener Listener for animation events . */
public void morphIntoFab ( View fab , long hideSheetDuration , long hideSheetColorDuration , AnimationListener listener ) { } }

implementation: revealSheetWithFab ( fab , getSheetRevealRadius ( ) , getFabRevealRadius ( fab ) , hideSheetDuration , sheetColor , fabColor , hideSheetColorDuration , listener ) ;


signature:
public class OverlayAnimation { /** * Hides the overlay .
 * @ param duration Duration of the animation in milliseconds . Use 0 for no animation .
 * @ param listener Listener for animation events . */
public void hide ( long duration , final AnimationListener listener ) { } }

implementation: overlay . animate ( ) . alpha ( 0 ) . setDuration ( duration ) . setInterpolator ( interpolator ) . setListener ( new AnimatorListenerAdapter ( ) { @ Override public void onAnimationStart ( Animator animation ) { if ( listener != null ) { listener . onStart ( ) ; } } @ Override public void onAnimationEnd ( Animator animation ) { overlay . setVisibility ( View . GONE ) ; if ( listener != null ) { listener . onEnd ( ) ; } } } ) . start ( ) ;


signature:
public class MaterialSheetFab { /** * Shows the FAB and sets the FAB ' s translation .
 * @ param translationX translation X value
 * @ param translationY translation Y value */
public void showFab ( float translationX , float translationY ) { } }

implementation:
// Update FAB ' s anchor
setFabAnchor ( translationX , translationY ) ; // Show the FAB in the new position if the sheet is not visible
if ( ! isSheetVisible ( ) ) { fab . show ( translationX , translationY ) ; }


signature:
public class MaterialSheetFab { /** * Shows the sheet . */
public void showSheet ( ) { } }

implementation:
if ( isAnimating ( ) ) { return ; } isShowing = true ; // Show overlay
overlayAnimation . show ( SHOW_OVERLAY_ANIM_DURATION , null ) ; // Morph FAB into sheet
morphIntoSheet ( new AnimationListener ( ) { @ Override public void onEnd ( ) { // Call event listener
if ( eventListener != null ) { eventListener . onSheetShown ( ) ; } // Assuming that this is the last animation to finish
isShowing = false ; // Hide sheet after it is shown
if ( hideSheetAfterSheetIsShown ) { hideSheet ( ) ; hideSheetAfterSheetIsShown = false ; } } } ) ; // Call event listener
if ( eventListener != null ) { eventListener . onShowSheet ( ) ; }


signature:
public class MaterialSheetFab { /** * Hides the sheet ( if visible ) and then hides the FAB . */
public void hideSheetThenFab ( ) { } }

implementation:
AnimationListener listener = new AnimationListener ( ) { @ Override public void onEnd ( ) { fab . hide ( ) ; } } ; // Hide sheet then hide FAB
if ( isSheetVisible ( ) ) { hideSheet ( listener ) ; } // Hide FAB
else { listener . onEnd ( ) ; }


signature:
public class MainActivity { /** * Sets up the action bar . */
private void setupActionBar ( ) { } }

implementation: setSupportActionBar ( ( Toolbar ) findViewById ( R . id . toolbar ) ) ; getSupportActionBar ( ) . setDisplayHomeAsUpEnabled ( true ) ;


signature:
public class MainActivity { /** * Sets up the navigation drawer . */
private void setupDrawer ( ) { } }

implementation: drawerLayout = ( DrawerLayout ) findViewById ( R . id . drawer_layout ) ; drawerToggle = new ActionBarDrawerToggle ( this , drawerLayout , R . string . opendrawer , R . string . closedrawer ) ; drawerLayout . setDrawerListener ( drawerToggle ) ;


signature:
public class MainActivity { /** * Sets up the tabs . */
private void setupTabs ( ) { } }

implementation:
// Setup view pager
ViewPager viewpager = ( ViewPager ) findViewById ( R . id . viewpager ) ; viewpager . setAdapter ( new MainPagerAdapter ( this , getSupportFragmentManager ( ) ) ) ; viewpager . setOffscreenPageLimit ( MainPagerAdapter . NUM_ITEMS ) ; updatePage ( viewpager . getCurrentItem ( ) ) ; // Setup tab layout
TabLayout tabLayout = ( TabLayout ) findViewById ( R . id . tabs ) ; tabLayout . setupWithViewPager ( viewpager ) ; viewpager . addOnPageChangeListener ( new ViewPager . OnPageChangeListener ( ) { @ Override public void onPageScrolled ( int i , float v , int i1 ) { } @ Override public void onPageSelected ( int i ) { updatePage ( i ) ; } @ Override public void onPageScrollStateChanged ( int i ) { } } ) ;


signature:
public class MainActivity { /** * Sets up the Floating action button . */
private void setupFab ( ) { } }

implementation:
Fab fab = ( Fab ) findViewById ( R . id . fab ) ; View sheetView = findViewById ( R . id . fab_sheet ) ; View overlay = findViewById ( R . id . overlay ) ; int sheetColor = getResources ( ) . getColor ( R . color . background_card ) ; int fabColor = getResources ( ) . getColor ( R . color . theme_accent ) ; // Create material sheet FAB
materialSheetFab = new MaterialSheetFab < > ( fab , sheetView , overlay , sheetColor , fabColor ) ; // Set material sheet event listener
materialSheetFab . setEventListener ( new MaterialSheetFabEventListener ( ) { @ Override public void onShowSheet ( ) { // Save current status bar color
statusBarColor = getStatusBarColor ( ) ; // Set darker status bar color to match the dim overlay
setStatusBarColor ( getResources ( ) . getColor ( R . color . theme_primary_dark2 ) ) ; } @ Override public void onHideSheet ( ) { // Restore status bar color
setStatusBarColor ( statusBarColor ) ; } } ) ; // Set material sheet item click listeners
findViewById ( R . id . fab_sheet_item_recording ) . setOnClickListener ( this ) ; findViewById ( R . id . fab_sheet_item_reminder ) . setOnClickListener ( this ) ; findViewById ( R . id . fab_sheet_item_photo ) . setOnClickListener ( this ) ; findViewById ( R . id . fab_sheet_item_note ) . setOnClickListener ( this ) ;


signature:
public class MainActivity { /** * Updates the FAB based on the selected page
 * @ param selectedPage selected page */
private void updateFab ( int selectedPage ) { } }

implementation: switch ( selectedPage ) { case MainPagerAdapter . ALL_POS : materialSheetFab . showFab ( ) ; break ; case MainPagerAdapter . SHARED_POS : materialSheetFab . showFab ( 0 , - getResources ( ) . getDimensionPixelSize ( R . dimen . snackbar_height ) ) ; break ; case MainPagerAdapter . FAVORITES_POS : default : materialSheetFab . hideSheetThenFab ( ) ; break ; }


signature:
public class MainActivity { /** * Updates the snackbar based on the selected page
 * @ param selectedPage selected page */
private void updateSnackbar ( int selectedPage ) { } }

implementation: View snackbar = findViewById ( R . id . snackbar ) ; switch ( selectedPage ) { case MainPagerAdapter . SHARED_POS : snackbar . setVisibility ( View . VISIBLE ) ; break ; case MainPagerAdapter . ALL_POS : case MainPagerAdapter . FAVORITES_POS : default : snackbar . setVisibility ( View . GONE ) ; break ; }


signature:
public class MainActivity { /** * Toggles opening / closing the drawer . */
private void toggleDrawer ( ) { } }

implementation: if ( drawerLayout . isDrawerVisible ( GravityCompat . START ) ) { drawerLayout . closeDrawer ( GravityCompat . START ) ; } else { drawerLayout . openDrawer ( GravityCompat . START ) ; }


signature:
public class SupportAnimator { /** * Experimental feature */
public SupportAnimator reverse ( ) { } }

implementation: if ( isRunning ( ) ) { return null ; } RevealAnimator target = mTarget . get ( ) ; if ( target != null ) { return target . startReverseAnimation ( ) ; } return null ;


signature:
public class FabAnimation { /** * Animates the FAB as if the FAB is morphing into a sheet .
 * @ param endX The X coordinate that the FAB will be moved to .
 * @ param endY The Y coordinate that the FAB will be moved to .
 * @ param side The side of the arc animation .
 * @ param arcDegrees Amount of arc in FAB movement animation .
 * @ param scaleFactor Amount to scale FAB .
 * @ param duration Duration of the animation in milliseconds . Use 0 for no animation .
 * @ param listener Listener for animation events . */
public void morphIntoSheet ( int endX , int endY , Side side , int arcDegrees , float scaleFactor , long duration , AnimationListener listener ) { } }

implementation: morph ( endX , endY , side , arcDegrees , scaleFactor , duration , listener ) ;


signature:
public class FabAnimation { /** * Animates the FAB as if a sheet is being morphed into a FAB .
 * @ param endX The X coordinate that the FAB will be moved to .
 * @ param endY The Y coordinate that the FAB will be moved to .
 * @ param side The side of the arc animation .
 * @ param arcDegrees Amount of arc in FAB movement animation .
 * @ param scaleFactor Amount to scale FAB .
 * @ param duration Duration of the animation in milliseconds . Use 0 for no animation .
 * @ param listener Listener for animation events . */
public void morphFromSheet ( int endX , int endY , Side side , int arcDegrees , float scaleFactor , long duration , AnimationListener listener ) { } }

implementation: fab . setVisibility ( View . VISIBLE ) ; morph ( endX , endY , side , arcDegrees , scaleFactor , duration , listener ) ;


signature: public class Person { @ NonNull @ Override public String getTextForDisplayMode ( MentionDisplayMode mode ) { } }

implementation: switch ( mode ) { case FULL : return getFullName ( ) ; case PARTIAL : String [ ] words = getFullName ( ) . split ( " " ) ; return ( words . length > 1 ) ? words [ 0 ] : "" ; case NONE : default : return "" ; }


signature:
public class SuggestionsAdapter { /** * Method to notify the adapter that a new { @ link QueryToken } has been received and that
 * suggestions will be added to the adapter once generated .
 * @ param queryToken the { @ link QueryToken } that has been received
 * @ param buckets a list of string dictating which buckets the future query results will go into */
public void notifyQueryTokenReceived ( QueryToken queryToken , List < String > buckets ) { } }

implementation: synchronized ( mLock ) { Set < String > currentBuckets = mWaitingForResults . get ( queryToken ) ; if ( currentBuckets == null ) { currentBuckets = new HashSet < > ( ) ; } currentBuckets . addAll ( buckets ) ; mWaitingForResults . put ( queryToken , currentBuckets ) ; }


signature:
public class SuggestionsAdapter { /** * Add mention suggestions to a given bucket in the adapter . The adapter tracks the latest result for every given
 * bucket , and passes this information to the SuggestionsManager to construct the list of suggestions in the
 * appropriate order .
 * Note : This should be called exactly once for every bucket returned from the query client .
 * @ param result a { @ link SuggestionsResult } containing the suggestions to add
 * @ param bucket a string representing the group to place the { @ link SuggestionsResult } into
 * @ param source the associated { @ link TokenSource } to use for reference */
public void addSuggestions ( final @ NonNull SuggestionsResult result , final @ NonNull String bucket , final @ NonNull TokenSource source ) { } }

implementation:
// Add result to proper bucket and remove from waiting
QueryToken query = result . getQueryToken ( ) ; synchronized ( mLock ) { mResultMap . put ( bucket , result ) ; Set < String > waitingForBuckets = mWaitingForResults . get ( query ) ; if ( waitingForBuckets != null ) { waitingForBuckets . remove ( bucket ) ; if ( waitingForBuckets . size ( ) == 0 ) { mWaitingForResults . remove ( query ) ; } } } // Rebuild the list of suggestions in the appropriate order
String currentTokenString = source . getCurrentTokenString ( ) ; synchronized ( mLock ) { mSuggestions . clear ( ) ; List < Suggestible > suggestions = mSuggestionsListBuilder . buildSuggestions ( mResultMap , currentTokenString ) ; // If we have suggestions , add them to the adapter and display them
if ( suggestions . size ( ) > 0 ) { mSuggestions . addAll ( suggestions ) ; mSuggestionsVisibilityManager . displaySuggestions ( true ) ; } else { hideSuggestionsIfNecessary ( result . getQueryToken ( ) , source ) ; } } notifyDataSetChanged ( ) ;


signature:
public class SuggestionsAdapter { /** * Hides the suggestions if there are no more incoming queries .
 * @ param currentQuery the most recent { @ link QueryToken }
 * @ param source the associated { @ link TokenSource } to use for reference */
private void hideSuggestionsIfNecessary ( final @ NonNull QueryToken currentQuery , final @ NonNull TokenSource source ) { } }

implementation: String queryTS = currentQuery . getTokenString ( ) ; String currentTS = source . getCurrentTokenString ( ) ; if ( ! isWaitingForResults ( currentQuery ) && queryTS != null && queryTS . equals ( currentTS ) ) { mSuggestionsVisibilityManager . displaySuggestions ( false ) ; }


signature:
public class SuggestionsAdapter { /** * Determines if the adapter is still waiting for results for a given { @ link QueryToken }
 * @ param currentQuery the { @ link QueryToken } to check if waiting for results on
 * @ return true if still waiting for the results of the current query */
private boolean isWaitingForResults ( QueryToken currentQuery ) { } }

implementation: synchronized ( mLock ) { Set < String > buckets = mWaitingForResults . get ( currentQuery ) ; return buckets != null && buckets . size ( ) > 0 ; }


signature:
public class MentionsLoader { /** * Returns a subset */
public List < T > getSuggestions ( QueryToken queryToken ) { } }

implementation: String prefix = queryToken . getKeywords ( ) . toLowerCase ( ) ; List < T > suggestions = new ArrayList < > ( ) ; if ( mData != null ) { for ( T suggestion : mData ) { String name = suggestion . getSuggestiblePrimaryText ( ) . toLowerCase ( ) ; if ( name . startsWith ( prefix ) ) { suggestions . add ( suggestion ) ; } } } return suggestions ;


signature:
public class WordTokenizer { /** * { @ inheritDoc } */
@ Override public int findTokenStart ( final @ NonNull Spanned text , final int cursor ) { } }

implementation:
int start = getSearchStartIndex ( text , cursor ) ; int i = cursor ; // If it is explicit , return the index of the first explicit character
if ( isExplicit ( text , cursor ) ) { i -- ; while ( i >= start ) { char currentChar = text . charAt ( i ) ; if ( isExplicitChar ( currentChar ) ) { if ( i == 0 || isWordBreakingChar ( text . charAt ( i - 1 ) ) ) { return i ; } } i -- ; } // Could not find explicit character before the cursor
// Note : This case should never happen ( means that isExplicit
// returned true when it should have been false )
return - 1 ; } else { // For implicit tokens , we need to go back a certain number of words to find the start
// of the token ( with the max number of words to go back defined in the config )
int maxNumKeywords = mConfig . MAX_NUM_KEYWORDS ; // Go back to the start of the word that the cursor is currently in
while ( i > start && ! isWordBreakingChar ( text . charAt ( i - 1 ) ) ) { i -- ; } // Cursor is at beginning of current word , go back MaxNumKeywords - 1 now
for ( int j = 0 ; j < maxNumKeywords - 1 ; j ++ ) { // Decrement through only one word - breaking character , if it exists
if ( i > start && isWordBreakingChar ( text . charAt ( i - 1 ) ) ) { i -- ; } // If there is more than one word - breaking space , break out now
// Do not consider queries with words separated by more than one word - breaking char
if ( i > start && isWordBreakingChar ( text . charAt ( i - 1 ) ) ) { break ; } // Decrement until the next space
while ( i > start && ! isWordBreakingChar ( text . charAt ( i - 1 ) ) ) { i -- ; } } // Ensures that text . char ( i ) is not a word - breaking or explicit char ( i . e . cursor must have a
// word - breaking char in front of it and a non - word - breaking char behind it )
while ( i < cursor && ( isWordBreakingChar ( text . charAt ( i ) ) || isExplicitChar ( text . charAt ( i ) ) ) ) { i ++ ; } return i ; }


signature:
public class WordTokenizer { /** * { @ inheritDoc } */
@ Override public int findTokenEnd ( final @ NonNull Spanned text , final int cursor ) { } }

implementation:
int i = cursor ; int end = getSearchEndIndex ( text , cursor ) ; // Starting from the cursor , increment i until it reaches the first word - breaking char
while ( i >= 0 && i < end ) { if ( isWordBreakingChar ( text . charAt ( i ) ) ) { return i ; } else { i ++ ; } } return i ;


signature:
public class WordTokenizer { /** * { @ inheritDoc } */
public boolean isValidMention ( final @ NonNull Spanned text , final int start , final int end ) { } }

implementation:
// Get the token
CharSequence token = text . subSequence ( start , end ) ; // Null or empty string is not a valid mention
if ( TextUtils . isEmpty ( token ) ) { return false ; } // Handle explicit mentions first , then implicit mentions
final int threshold = mConfig . THRESHOLD ; boolean multipleWords = containsWordBreakingChar ( token ) ; boolean containsExplicitChar = containsExplicitChar ( token ) ; if ( ! multipleWords && containsExplicitChar ) { // If it is one word and has an explicit char , the explicit char must be the first char
if ( ! isExplicitChar ( token . charAt ( 0 ) ) ) { return false ; } // Ensure that the character before the explicit character is a word - breaking character
// Note : Checks the explicit character closest in front of the cursor
if ( ! hasWordBreakingCharBeforeExplicitChar ( text , end ) ) { return false ; } // Return true if string is just an explicit character
if ( token . length ( ) == 1 ) { return true ; } // If input has length greater than one , the second character must be a letter or digit
// Return true if and only if second character is a letter or digit , i . e . " @ d "
return Character . isLetterOrDigit ( token . charAt ( 1 ) ) ; } else if ( token . length ( ) >= threshold ) { // Change behavior depending on if keywords is one or more words
if ( ! multipleWords ) { // One word , no explicit characters
// input is only one word , i . e . " u41"
return onlyLettersOrDigits ( token , threshold , 0 ) ; } else if ( containsExplicitChar ) { // Multiple words , has explicit character
// Must have a space , the explicit character , then a letter or digit
return hasWordBreakingCharBeforeExplicitChar ( text , end ) && isExplicitChar ( token . charAt ( 0 ) ) && Character . isLetterOrDigit ( token . charAt ( 1 ) ) ; } else { // Multiple words , no explicit character
// Either the first or last couple of characters must be letters / digits
boolean firstCharactersValid = onlyLettersOrDigits ( token , threshold , 0 ) ; boolean lastCharactersValid = onlyLettersOrDigits ( token , threshold , token . length ( ) - threshold ) ; return firstCharactersValid || lastCharactersValid ; } } return false ;


signature:
public class WordTokenizer { /** * { @ inheritDoc } */
public boolean isExplicitChar ( final char c ) { } }

implementation: final String explicitChars = mConfig . EXPLICIT_CHARS ; for ( int i = 0 ; i < explicitChars . length ( ) ; i ++ ) { char explicitChar = explicitChars . charAt ( i ) ; if ( c == explicitChar ) { return true ; } } return false ;


signature:
public class WordTokenizer { /** * { @ inheritDoc } */
public boolean isWordBreakingChar ( final char c ) { } }

implementation: final String wordBreakChars = mConfig . WORD_BREAK_CHARS ; for ( int i = 0 ; i < wordBreakChars . length ( ) ; i ++ ) { char wordBreakChar = wordBreakChars . charAt ( i ) ; if ( c == wordBreakChar ) { return true ; } } return false ;


signature:
public class WordTokenizer { /** * Returns the explicit character if appropriate ( i . e . within the keywords ) .
 * If not currently explicit , then returns the null character ( i . e . ' / 0 ' ) .
 * @ param text String to get the explicit character from
 * @ param cursor position of the cursor in text
 * @ return the current explicit character or the null character if not currently explicit */
public char getExplicitChar ( final @ NonNull CharSequence text , final int cursor ) { } }

implementation:
if ( cursor < 0 || cursor > text . length ( ) ) { return ( char ) 0 ; } SpannableStringBuilder ssb = new SpannableStringBuilder ( text ) ; int start = getSearchStartIndex ( ssb , cursor ) ; int i = cursor - 1 ; int numWordBreakingCharsSeen = 0 ; while ( i >= start ) { char currentChar = text . charAt ( i ) ; if ( isExplicitChar ( currentChar ) ) { // Explicit character must have a word - breaking character before it
if ( i == 0 || isWordBreakingChar ( text . charAt ( i - 1 ) ) ) { return currentChar ; } else { // Otherwise , explicit character is not in a valid position , return null char
return ( char ) 0 ; } } else if ( isWordBreakingChar ( currentChar ) ) { // Do not allow the explicit mention to exceed
numWordBreakingCharsSeen ++ ; if ( numWordBreakingCharsSeen == mConfig . MAX_NUM_KEYWORDS ) { // No explicit char in maxNumKeywords , so return null char
return ( char ) 0 ; } } i -- ; } return ( char ) 0 ;


signature:
public class WordTokenizer { /** * Returns true if the input string contains an explicit character .
 * @ param input a { @ link CharSequence } to test
 * @ return true if input contains an explicit character */
public boolean containsExplicitChar ( final @ NonNull CharSequence input ) { } }

implementation: if ( ! TextUtils . isEmpty ( input ) ) { for ( int i = 0 ; i < input . length ( ) ; i ++ ) { char c = input . charAt ( i ) ; if ( isExplicitChar ( c ) ) { return true ; } } } return false ;


signature:
public class WordTokenizer { /** * Returns true if the input string contains a word - breaking character .
 * @ param input a { @ link CharSequence } to test
 * @ return true if input contains a word - breaking character */
public boolean containsWordBreakingChar ( final @ NonNull CharSequence input ) { } }

implementation: if ( ! TextUtils . isEmpty ( input ) ) { for ( int i = 0 ; i < input . length ( ) ; i ++ ) { char c = input . charAt ( i ) ; if ( isWordBreakingChar ( c ) ) { return true ; } } } return false ;