[Android] Development of dry goods - technology sharing of high imitation QQ skinning SkinEngine implementation

First show screenshots


[Foreword description] This technology has been used since android QQ2.0 until the current QQ5.9 version. I will explain the code and implementation principle in detail. At present, this technology is rarely mentioned in some blogs such as Baidu or google. The general principle is to reflect the Resources class through java. There is a sPreloadedDrawables variable in the Resources class. This is the key point. Its function is to realize the preloading of Drawable pictures, and control or obtain pictures through the Resources.getDrawable(resId) method when the APP is running. , but getDrawable will get the image from sPreloadedDrawables, but this method is not a foolproof solution, it may change due to API changes.


1. We see that there are three buttons on this interface, then click the "Skin Now" button


At this moment, we found that the small robot icon on the interface has been replaced with a music icon with a blue background


Next, we click "Jump" to the AbcActivity interface to see the effect.


We found that the pictures were also replaced in AbcActivity, so let's take a look at the interface layout of AbcActivity

In the layout file, we found that ImageView did not set the control id at all, so how is the picture on this control replaced? Next, we will analyze it step by step.

Second, the principle analysis and implementation

In the SkinEngine class we create the following two methods and intercept the sPreloadedDrawables variable in the Resources class in the initIntercepter method. Then do related interception processing by defining DrawablePreloadIntercepter.


Let DrawablePreloadIntercepter inherit LongSparseArray<Drawable.ConstantState> and override the get method.


In the get method, we first create the mKeyToResourcesId variable to store the skin resources that need to be replaced, and add an external add method. When replacing the skin, add the resource id to mKeyToResourcesId in the Activity. At this time, when the system obtains the resource through the get method, it determines whether the key corresponding to the resource file exists in mKeyToResourcesId. If it does not exist, the original image resource is returned. If it exists, the loadConstantState method in the SkinEngine class is called to load the skin resource.


In the loadConstantState method of the SkinEngine class , we first get the resource file name through the getValue method of Resources, then load the file corresponding to the resource file name in the assets directory (here can be changed to load from the sd card) and then create a Bitmap through BitmapFactory , and convert Bitmap to Drawable.ConstantState object through SkinnableBitmapDrawable class. I have already written the SkinnableBitmapDrawable class, which can be used directly.


At this point, you can use the skinning function in the Activity. The method of use is as follows


Pay attention to the reloadDrawable method, this method is only to refresh the current Activity, you do not need to do this operation in other Activity.


Next, let's talk about the SkinEngine.getInstances().run() method. It's very simple. We also need to reflect the mDrawableCache object in the Resources class, which is used to cache the resources of sPreloadedDrawables. We just replaced and intercepted sPreloadedDrawables. At this time, we need to clear the cached resources in mDrawableCache, and then use the reloadDrawable method to re-take the pictures in the page from the Resource. At this point you will find that the skinning function has been completed.


接下来说说如何取消换肤,还记DrawablePreloadIntercepter中的mOldPreloadCache变量吗?当时在SkinEngine中的initIntercepter方法中我就已经将Resources类的sPreloadedDrawables变量保存下来了


使用方法,直接在Activity调用即可,然后在重新从Resources中拿一下资源。


好了,最后android的SkinEngine就已经完成了,接下来大家最关心的当然还是源码,那么我就无私的献上了,注意,下载需要1点积分,评论一下就赚回来了,就当时给我谢了这么久代码的一点点支持吧O(∩_∩)O~~


三,代码分享


http://download.csdn.net/detail/cc_want/9187187

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325520125&siteId=291194637