Efficient Bitmap loading

  • Use bitmapFactory. Options to load the required dimensions
  • The sampling scale
  • Set sampling rate
  • ImSampleSize scaling example 200 times 200 set to 2 resulting in 100 times 100

Sampling rate

  • Set bitmapFactory. Options to True and load the image to inJustDecodeBounds
  • Get the original width and height information for the image from bitmapFactory. Options, which correspond to outWidth and outHeight
  • Calculate the sampling rate inSampleSize according to the sampling rate rule and the size of the target View
  • Set bitmapFactory. Options to false to inJustDecodeBounds and reload the image

Android cache strategy

Delete old cache add new cache, so how do you define old cache and new cache as a strategy

Different cache policies correspond to different cache algorithms

  • The old and new files are defined according to the last modification time of the file

Common cache algorithms: LRU (Least Recently Used) Algorithm Used Least Recently

  • Core idea: When the cache is full, the least recently used cache objects are preferentially eliminated
  • Two types: LruCache and DiskLruCache
  • LruCache memory storage cache, DiskLruCache storage device cache, the perfect combination of the two, is very convenient to achieve a high value of ImageLoader

LruCache

  • Android3.1 provide
  • A generic class
  • Internally, a LinkedHashMap is used to store external cache objects as strong references
  • When the store is full, the older cache object is removed and a new cache object is added
  • Strong references: Direct object references
  • Soft references: When only soft references exist for an object, insufficient memory is reclaimed by the GC
  • Weak references: When only weak references exist for an object, the object is reclaimed by the GC
  • Thread safety

LruCache cache implementation process

  • Provides the total capacity size of the cache

= override sizeOf

package com.example.androidperformance

import android.graphics.Bitmap
import android.util.LruCache

/** * cache singleton class */
object CacheUtils {
    
    fun getMemoryCache(a) : LruCache<String, Bitmap> {
        val maxMemory = (Runtime.getRuntime().maxMemory() / 1024).toInt()
        val cacheSize = maxMemory / 8
        return object : LruCache<String, Bitmap>(cacheSize) {
            override fun sizeOf(key: String, bitmap: Bitmap): Int {
                return bitmap.rowBytes * bitmap.height / 1024}}}fun putBitmapCache(key: String, bitmap: Bitmap) {
        getMemoryCache().put(key, bitmap)
    }
    
    fun getBitmapWithKey(key: String) {
        getMemoryCache().get(key)
    }
    
    fun deleteBitmapWithKey(key: String) {
        getMemoryCache().remove(key)
    }
}
Copy the code

DiskLruCache Disk cache

Create open method open (directory: File, appVersion: int, valueCount: int, maxSize: long)

  • The first parameter: the cache directory of SD card/sdcard/Android/data/package_name/cache application is unloaded, directory to be deleted advice: if you want to uninstall the data to delete, select the data under the current directory, instead, choose other directory
  • Second parameter: Application version number: Generally set to 1
  • Third parameter: the number of data corresponding to a single node
  • The fourth parameter: total cache size: for example, 50MB. If it exceeds 50MB, it will be automatically deleted. Ensure that the value is not greater than this value

DiskLruCache cache is added

  • Edit object by Editer
  • The MD5 value of the URL is added as the key
  • editor.commit()

DiskLruCache Cache lookup

  • Url is converted to key
  • Get the Snapshot object using the get method of DiskLruCache
  • Get the input and output streams of the cache file from the Snapshot object

ImageLoader

  • Synchronous loading of images
  • Asynchronous loading of images
  • Image compression design an ImageResizer class can be
  • Memory cache
  • Disk cache LruCache DiskLruCache
  • Network pull uses thread pool to load images reason: Common threads slide along the list and create too many, which is not conducive to overall efficiency

AsyncTask does not support versions below 3.0, so Runnable+ thread pool is used to solve this problem

ImageLoader handles the mismatch of ImageView reuse for multithreaded image downloads

  • Fix this problem by setting a TAG value for the ImageView
  • Get the uri of the image and compare it to the URI of the ImageView

Gracefully solve list stutter

  • Do not perform time-consuming operations in getView
  • Control the execution frequency of asynchronous tasks, for example, the user frequently swipes up and down, resulting in hundreds of asynchronous tasks at a moment
  • Congestion in the thread pool and frequent UI updates didn’t make sense
  • And UI updates are in the main thread, which can cause a certain amount of lag
  • How to solve it?
  • Consider stopping asynchronous loading while the list is scrolling
  • Even though the process is asynchronous, you still get a good user experience when the list stops scrolling
  • In onScrollStateChanged approach, set up the rolling state, stop calling Adapter. The notifyDataSetChanged
  • Then, in getView, load the image only when the list is still
  • Enabling Hardware Acceleration

Memory leak optimization

  • Use the memory leak analysis tool MAT
  • Maintainability and extensibility of code
  • Good code style
  • Clear code hierarchy
  • Code scalability, reasonable design patterns
  • Optimization for memory leaks caused by static variables: Static variables refer to objects with a lifetime (such as activities)
  • The singleton pattern causes a memory leak: lack of deregistration causes underegistration in onDestory
  • Memory leak caused by property animation: An infinite loop animation loops through the Activity and does not stop the animation in onDestory, which will cause the animation to continue playing when the Activity is destroyed. Use animator.cancel() to stop the animation

Layout optimization

  • Reduce the hierarchy of layout files
  • Delete unnecessary controls and layers
  • The < include > tag
  • ViewSub loads on demand

Draw the optimization

  • OnDraw does not create local objects repeatedly
  • Don’t do time-consuming tasks inside onDraw
  • OnDraw cannot perform thousands of loop operations

Response speed optimization

  • Core: Avoid time-consuming operations in the main thread
  • Put time-consuming operations in child threads
  • If you do too much in the main thread, your Activity will have a black screen or even an ANR
  • Android states that ANR will occur if Activitydoes not respond to on-screen touch events or keyboard input events within 5 seconds

ANR log analysis

  • When ANR problems occur, the system will create a file called testamp.txt in the data/ ANR directory. This file can be used to locate the cause of ANR problems
  • For example, if you sleep for 30 seconds in the main thread and repeatedly click the screen, ANR will appear. At this time, you can analyze the file
  • When the child thread and the main thread preempt the synchronous lock, the two time-consuming ANR methods also wait for the lock of a Activiy at the same time, which causes the problem of waiting for each other

RecyclerView and Bitmap optimization

  • Avoid time-consuming operations in getView
  • Control the execution frequency of tasks according to the sliding state of the list

Thread optimization

  • Adopting thread pools
  • Avoid using too many threads in your program
  • Because the thread pool can be reused, it effectively controls the maximum number of concurrent requests and prevents a large number of threads from grabbing system resources and causing blocking

Other optimization

  • Avoid creating too many objects repeatedly
  • Do not use enumerations too much, because they take up more memory than orthopedics
  • Constants need to be modified with static final
  • Use Android-specific data structures, such as SparseArray and Pair
  • Use weak references and software appropriately
  • Memory cache + disk cache
  • Use static inner classes whenever possible to avoid potential memory leaks due to inner classes

Memory leak tool Profiler

Improve the maintainability of applications

Code style.

  • Private member variables start with m, static members start with S, and constants are capitalized
  • Reasonable space
  • Add comments only for critical code
  • The hierarchy of code
  • Single responsibility
  • Extensible programming
  • Design patterns

Recommended books

Big Talk Design Mode

Android source code design pattern analysis and combat