当前位置:网站首页>Interviewer: let you design a set of image loading framework. How would you design it?
Interviewer: let you design a set of image loading framework. How would you design it?
2022-07-28 06:11:00 【Android technology circle】
Preface :
Many students will be asked about the knowledge of image loading in the interview .
The following is a simulated interview :
interviewer : Do you know about image loading ?
I …
interviewer : How to cache pictures ?
I …
interviewer :Glide You know , Tell me about your right Glide View of the ?
I …
interviewer : Let yourself design a set of image loading framework , How do you design ?
The interviewer will ask you step by step , The ultimate goal may be to make you Design a picture loading framework by yourself , How would you design ? Don't read the following first , Think for yourself , What is the design idea ?
…
Okay , It doesn't matter if you don't think about it well , After reading this article, you will understand .
Let's talk about the steps we need to take in our usual network requests
- 1. Assemble our request entity class , The internal encapsulation of the request requires
url,header, And some parameter information - 2. By requesting information , Go to
Memory cacheIn order to get , Not to goLocal diskFind whether there is cached data in the cache , If there is ,Remember that the data cached in the disk is metadata , After decoding , Can be used, The decoded data is retrieved orHandlerTo the business layer - 3. No cache data , You need to pull data from the server , This process requires asynchronous loading , Thread pool may be a good choice
- 4. After data acquisition , First the
MetadataThe cache todisk, Then decode the picture data , After decoding , The cache toMemory cachein , Finally, call back the decoded response data to the business layer .
The above is a complete Image loading request The process of :
Use a graph to represent :

Let's consider what we need to do from the process :
According to the first step :
Assemble our request entity class , The internal encapsulation of the request requires url,header, And some parameter information
here Ideas :
1. To design a Request The interface of , Start request and pause request can be called in the interface , And get our request status and other methods ,
public interface Request {
/** To request */
void begin();
/** Clear the current request data */
void clear();
/** Pause request */
void pause();
/** View request in progress */
boolean isRunning();
/** Check whether the request succeeds in obtaining data , And finish */
boolean isComplete();
/** Check whether the request is cleared */
boolean isCleared();
}
2. Achieve this Request Interface , Assuming that SingleRequest, In this class, you may need Request status , The length and width properties of the incoming request control , Requested url Information , Request parameter information :
public final class SingleRequest<R> implements Request {
// This url Why is it a object Well , Because it's not necessarily imported String, It may be encapsulated String url Other classes of
private final Object url;
/** The length and width of the control */
private int width;
private int height;
/** Requested parameter information , This is externally configurable */
private final BaseRequestOptions<?> requestOptions;
// Here is the status information of a request , The loading process can be different according to the state , Do different things
private enum Status {
/** Created but not yet running. */
PENDING,
/** In the process of fetching media. */
RUNNING,
/** Waiting for a callback given to the Target to be called to determine target dimensions. */
WAITING_FOR_SIZE,
/** Finished loading media successfully. */
COMPLETE,
/** Failed to load media, may be restarted. */
FAILED,
/** Cleared by the user with a placeholder set, may be restarted. */
CLEARED,
}
...
// Of course, it needs to be realized Request Methods in interfaces
...
...
}
Follow the steps 2:
By requesting information , Go to the local cache to find whether there is cached data , If there is , Directly use the data in the cache , Through callback or
HandlerTo the business layer
Here we can design a L3 cache : Respectively :
- Disk caching :
DiskLruCache, There are many open source frameworks on the network , It can be used directly , Or design a set according to your own needs , It is recommended to use factory mode to create , This can better expand to the outside - Memory cache :
MemoryCache: This cache holds strong references to cached data , To prevent the gc It's recycled , This can also be made into an interface , The interface encapsulation method is as follows : Some basic operations :put,remove,clearEmpty cache , Monitor the memory condition of the device , Reclaim cache in time , preventOOM.
public interface MemoryCache {
// First you have to have put Method
Resource<?> put(@NonNull Key key, @Nullable Resource<?> resource);
// Need to have remove Method
Resource<?> remove(@NonNull Key key);
// Empty cache
void clearMemory();
// Monitor memory status
void trimMemory(int level);
// Get the current cache size information
long getCurrentSize();
...
Other methods
}
Use one LruResourceCache To achieve MemoryCache Methods in interfaces . We learned that Android The system provides us with a LruCache Memory cache class , Give Way LruResourceCache Inherit this directly LruCache That is to achieve our memory cache .
The inheritance relationship is as follows :
public class LruResourceCache extends LruCache<Key, Value> implements MemoryCache
Then all our cache requests , Can be directly submitted to the parent class LruCache To do , Only achieve MemoryCache Interface , somewhat The proxy pattern It's too delicious …
There may be some students who want to say , Your memory cache , If you pack too much , Isn't there a memory overflow or even OOM Well ? good , Then we need to introduce our first 3 Level cache :
Weak reference cache: We create aActiveResourcesCache: This class is also a memory cache , Then there are students to say , Didn't you design a cache before , Why design a memory cache again
Don't worry don't worry ..
Let's talk about this cache and the previous MemoryCache What's the difference : In this class, we use a HashMap To store the current cached data
Map<Key, ResourceWeakReference> activeEngineResources = new HashMap<>();
Create a ReferenceQueue To monitor the current cache data recycling status
private final ReferenceQueue<EngineResource<?>> resourceReferenceQueue = new ReferenceQueue<>();
What is the purpose of this ?
- 1. When memory is tight and resources need to be recycled , The first thing to recycle is the cache in weak references , This can prevent applications OOM.
- 2. In some cases , We can put the data into the L2 cache MemoryCache in , Prevent being recycled .
Cache access method : Go to the L3 cache first ActiveResourcesCache Get weak reference data in , If you can't get it , Then go to the L2 cache MemoryCache In order to get , Finally, get from the disk cache .
The above is a good implementation of our Three level cache mechanism
Okay, step 2 That's all
Continue with step 3:
No cache data , You need to pull data from the server , This process requires asynchronous loading , Thread pool may be a good choice
What information can we extract in this step :
1. Load asynchronously : Because pictures are loaded in a short time concurrently , So we need to use thread pool to solve , It is recommended to set the number of core threads in the thread pool to 0, Set a large value for the number of non core threads , Try to meet multiple concurrent requirements
public final class AndroidExecutor implements ExecutorService {
// Different types of thread pools can be created according to specific needs
//
public ThreadPoolExecutor getThreadPollExcutor{
return new ThreadPoolExecutor(
corePoolSize,//0
maximumPoolSize,//10
/*keepAliveTime=*/ threadTimeoutMillis,
TimeUnit.MILLISECONDS,
new PriorityBlockingQueue<Runnable>(),
new DefaultThreadFactory(
threadFactory, name, uncaughtThrowableStrategy, preventNetworkOperations));
}
}
- There are many different states in the image loading process : Such as initialization
initstate , Data loadingrunning, Data loadingSuccess, Loading failedFail, Data cache operation , Original data decoding and other operations . You can use oneJobClass to manage our network loading process :
class Job<R> implements Runnable{
public void run{
Execute the run Logic , For different Job The status is handled differently
}
}
Every Job Represents a state , Logic to deal with , Maybe the same Job Multiple states need to be processed continuously .
Look at the steps 4:
After data acquisition , Decode the picture data , After decoding , Cache locally , Then call back the decoded response data to the business layer .
We extract key information : Picture decoding , Image caching , Callback response business layer
Picture decoding: Because the pictures are on some low memory devices , You may also need to do downsampling , Cutting and so on : The decoding logic is as follows :- 1. First use options.inJustDecodeBounds = true: Get the width and height of the picture
- 2. Get the actual control Target Width and height , and 1 Cut the data by comparison
- 3. Then decode the original data into the required size
Image caching: We do caching twice , After getting the metadata requested by the server ,Cache to disk, This step requires asynchronous processing . Then onMetadatadecode , The obtained data , Put inMemory cachein , So when taking , Get the cache from the memory cache first , Only when there is no data can you get data from the disk , The data in the disk is metadata , You need to use decoding to be used by the control
In fact, there is a layer by layer correspondence between before and after data loading , Including our cache processing logic
- Callback response business layer : We encapsulate the response data and use the main thread callback to give it to the business layer .
Okay , The above is the process of designing a standard network application framework .
Besides the above, what else should we pay attention to ?
1. Let's imagine if a control is
The destruction了 , But our task continues. What will happen ? by the way , There will beout of memoryThe situation of So we need to manage the lifecycle and tasks of controls . The management life cycle needs to be connected with your incomingtargetrelation , If it isActivityperhapsFragmentOfActivity, You can monitor the lifecycle of these components If it isApplicationOf , Need to monitorApplicationOfLife cycle.
Is there anything else to add ?
by the way , There is also image loading animation , List animation loading
ViewReuse of ,BitmapReuse and recycling , Are all aspects that we should consider .
anything else ??
This time it's really gone ..
Finally, let's summarize what we have said :
The design of an image loading framework needs attention :
- 1. Load data asynchronously : Thread pool
- 2. Thread switching :Handler
- 3. Need to support multiple image formats to load
- 4. Use multilevel caching : disk , Memory , Weak references ,
- 5. prevent OOM: Weak reference , The storage location of image byte array is as native
- 6. Life cycle management
- 7. Resource decoding downsampling
- 8.Bitmap Recycle and reuse
summary
A careful friend may find , What I explained above is Glide It realizes , These large open source frameworks have helped us deal with , We only need reuse , There is no need to build wheels again. Some large open source frameworks have helped us deal with it , We only need reuse , There's no need to make wheels again , But you must know the principle of the framework .
边栏推荐
- Reinforcement learning - incomplete observation problem, MCTs
- Deep learning (self supervision: Moco V2) -- improved bases with momentum contractual learning
- 神经网络学习
- TensorFlow2.1基本概念与常见函数
- Nlp项目实战自定义模板框架
- Dataset类分批加载数据集
- Construction of redis master-slave architecture
- 深度学习(自监督:MoCo V3):An Empirical Study of Training Self-Supervised Vision Transformers
- 小程序开发如何提高效率?
- 小程序开发
猜你喜欢

小程序开发系统有哪些优点?为什么要选择它?

self-attention学习笔记

Wechat applet development and production should pay attention to these key aspects

What about the app store on wechat?

3: MySQL master-slave replication setup

Deep learning (self supervision: simpl) -- a simple framework for contractual learning of visual representations

Which is more reliable for small program development?

How much does it cost to make a small program mall? What are the general expenses?

Kotlin语言现在怎么不火了?你怎么看?

微信小程序开发语言一般有哪些?
随机推荐
用于快速低分辨率人脸识别模型训练的改进知识蒸馏《Improved Knowledge Distillation for Training Fast LR_FR》
Deep learning (self supervised: Moco V3): An Empirical Study of training self supervised vision transformers
SQLAlchemy使用相关
无约束低分辨率人脸识别综述一:用于低分辨率人脸识别的数据集
transformer的理解
NLP project actual custom template framework
小程序开发流程详细是什么呢?
深度学习(自监督:MoCo V3):An Empirical Study of Training Self-Supervised Vision Transformers
小程序开发哪家更靠谱呢?
2: Why read write separation
深度学习(增量学习)——ICCV2021:SS-IL: Separated Softmax for Incremental Learning
神经网络实现鸢尾花分类
深度学习(自监督:SimCLR)——A Simple Framework for Contrastive Learning of Visual Representations
Invalid packaging for parent POM x, must be “pom“ but is “jar“ @
Four perspectives to teach you to choose applet development tools?
What is the detail of the applet development process?
深度学习(自监督:SimSiam)——Exploring Simple Siamese Representation Learning
Which is more reliable for small program development?
自动定时备份远程mysql脚本
深度学习——MetaFormer Is Actually What You Need for Vision