Android image loading progress monitoring based on glide v4. X
Glide is an excellent image loading framework, which can be used with simple configuration, saving developers a lot of effort. However, it does not provide an API for the progress of loading pictures. It takes a lot of trouble to implement such a demand.
attempt
When meeting this demand, the first reaction is that someone must have realized it online. You might as well learn from others' experience.
Glide loading pictures to achieve progress bar effect
Unfortunately, this implementation is based on version 3.7. The glide above version 4.0 has been greatly changed, and the using function has been removed
using() The using() API was removed in Glide 4 to encourage users to register their components once with a AppGlideModule to avoid object re-use. Rather than creating a new ModelLoader each time you load an image,you register it once in an AppGlideModule and let Glide inspect your model (the object you pass to load()) to figure out when to use your registered ModelLoader. To make sure you only use your ModelLoader for certain models,implement handles() as shown above to inspect each model and return true only if your ModelLoader should be used.
reflection
You have to use the latest version and want to add functions to it. You can't have both? How can I give up easily when I am "greedy for the new and tired of the old". I sorted out the requirements for loading picture progress again and found that other ideas can be used to simplify it:
Therefore, if you can monitor the download progress of the picture, it is probably the loading progress of the picture. Do you have to download the picture first and then give it to glide to load? No, glide supports the integration of other network modules, such as okhttp, and we can also use its interface to implement our own network loading module if we like.
The official warehouse of glide provides the integration module of okhttp, so I went to these codes to find a breakthrough.
Breach
Okhttp module is very simple. There are only four files, and none of them is long
First of all, those who have used glide know that the class inheriting glidemodule is used to set the configuration information of glide and load the module. In okhttpglidemodule, a component for loading glideurl type is registered with the system, which can be understood as a component for loading network pictures.
The okhttploader file is also very simple. It implements the modelloader interface. Here, modelloader is the abstract resource loader representation of glide. For example, here, the model of glideurl is loaded and the InputStream is returned, that is, the input stream of the picture. For details on glide's loaddata, model and fetch, you can view @ L_ 404_ 1@
The ultimate goal of okhttploader is to return a loaddata object. Now the situation is clear. The glide framework uses this loaddata object to get the input stream of the picture, so as to download the picture and load it after a series of decoding, clipping, caching and other operations. The parameter of loaddata has an okhttpstreamfetcher. From the name, this must be the place to download pictures. Let's continue.
You can see that all the key points are in the loaddata function. Do you think it's easy for students who have used okhttp? ha-ha.
Here, the InputStream of the picture is directly obtained, and then returned through the callback function callback. Ondataready()
Here's the problem. It's passed from the glide framework of callback. We can't control it. I tried to find the place where loaddata was called, but I didn't find it. What should I do? Let's see the final realization.
realization
In the loaddata function, there is such a code
Contentlengthinputstream is a tool class of glide, which is used to read the input stream. Click in and find several read methods
Therefore, my solution is to calculate the download progress and report the progress here, copy this class from the source code, replace the contentlengthinputstream in the okhttp module, and insert my own download progress logic here.
The specific code implementation will not be posted. Write a general idea:
When downloading a picture, pass in the picture progress monitoring. Save the monitoring instance in a collection container, such as map. The key is the URL. After calculating the download progress, find the corresponding callback through the URL to return the progress. After the picture is loaded, remove the callback from the collection (glide provides the callback after the picture is loaded).
OK, in this way, you are welcome to point out some unreasonable places, and please don't hesitate to give advice on better and more elegant implementation methods. I also hope you can support programming tips.