package com.example.qyh.joe.theme;
import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.text.TextUtils;
import com.example.qyh.joe.theme.attr.SkinView;
import com.example.qyh.joe.theme.callback.ISkinChangedListener;
import com.example.qyh.joe.theme.callback.ISkinChangingCallback;
import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SkinManager
{
private Context mContext;
private Resources mResources;
private ResourceManager mResourceManager;
private PrefUtils mPrefUtils;
private boolean usePlugin;
/**
* 换肤资源后缀
*/
private String mSuffix = "";
private String mCurPluginPath;
private String mCurPluginPkg;
private Map<ISkinChangedListener, List<SkinView>> mSkinViewMaps = new HashMap<ISkinChangedListener, List<SkinView>>();
private List<ISkinChangedListener> mSkinChangedListeners = new ArrayList<ISkinChangedListener>();
private SkinManager()
{
}
private static class SingletonHolder
{
static SkinManager sInstance = new SkinManager();
}
public static SkinManager getInstance()
{
return SingletonHolder.sInstance;
}
public void init(Context context)
{
mContext = context.getApplicationContext();
mPrefUtils = new PrefUtils(mContext);
String skinPluginPath = mPrefUtils.getPluginPath();
String skinPluginPkg = mPrefUtils.getPluginPkgName();
mSuffix = mPrefUtils.getSuffix();
if (TextUtils.isEmpty(skinPluginPath))
return;
File file = new File(skinPluginPath);
if (!file.exists()) return;
try
{
loadPlugin(skinPluginPath, skinPluginPkg, mSuffix);
mCurPluginPath = skinPluginPath;
mCurPluginPkg = skinPluginPkg;
} catch (Exception e)
{
mPrefUtils.clear();
e.printStackTrace();
}
}
private void loadPlugin(String skinPath, String skinPkgName, String suffix) throws Exception
{
//checkPluginParams(skinPath, skinPkgName);
AssetManager assetManager = AssetManager.class.newInstance();
Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
addAssetPath.invoke(assetManager, skinPath);
Resources superRes = mContext.getResources();
mResources = new Resources(assetManager, superRes.getDisplayMetrics(), superRes.getConfiguration());
mResourceManager = new ResourceManager(mResources, skinPkgName, suffix);
usePlugin = true;
}
private boolean checkPluginParams(String skinPath, String skinPkgName)
{
if (TextUtils.isEmpty(skinPath) || TextUtils.isEmpty(skinPkgName))
{
return false;
}
return true;
}
private void checkPluginParamsThrow(String skinPath, String skinPkgName)
{
if (!checkPluginParams(skinPath, skinPkgName))
{
throw new IllegalArgumentException("skinPluginPath or skinPkgName can not be empty ! ");
}
}
public void removeAnySkin()
{
clearPluginInfo();
notifyChangedListeners();
}
public boolean needChangeSkin()
{
return usePlugin || !TextUtils.isEmpty(mSuffix);
}
public ResourceManager getResourceManager()
{
if (!usePlugin)
{
mResourceManager = new ResourceManager(mContext.getResources(), mContext.getPackageName(), mSuffix);
}
return mResourceManager;
}
/**
* 应用内换肤,传入资源区别的后缀
*
* @param suffix
*/
public void changeSkin(String suffix)
{
clearPluginInfo();//clear before
mSuffix = suffix;
mPrefUtils.putPluginSuffix(suffix);
notifyChangedListeners();
}
private void clearPluginInfo()
{
mCurPluginPath = null;
mCurPluginPkg = null;
usePlugin = false;
mSuffix = null;
mPrefUtils.clear();
}
private void updatePluginInfo(String skinPluginPath, String pkgName, String suffix)
{
mPrefUtils.putPluginPath(skinPluginPath);
mPrefUtils.putPluginPkg(pkgName);
mPrefUtils.putPluginSuffix(suffix);
mCurPluginPkg = pkgName;
mCurPluginPath = skinPluginPath;
mSuffix = suffix;
}
public void changeSkin(final String skinPluginPath, final String pkgName, ISkinChangingCallback callback)
{
changeSkin(skinPluginPath, pkgName, "", callback);
}
/**
* 根据suffix选择插件内某套皮肤,默认为""
*
* @param skinPluginPath
* @param pkgName
* @param suffix
* @param callback
*/
public void changeSkin(final String skinPluginPath, final String pkgName, final String suffix, ISkinChangingCallback callback)
{
if (callback == null)
callback = ISkinChangingCallback.DEFAULT_SKIN_CHANGING_CALLBACK;
final ISkinChangingCallback skinChangingCallback = callback;
skinChangingCallback.onStart();
checkPluginParamsThrow(skinPluginPath, pkgName);
if (skinPluginPath.equals(mCurPluginPath) && pkgName.equals(mCurPluginPkg))
{
return;
}
new AsyncTask<Void, Void, Void>()
{
@Override
protected Void doInBackground(Void... params)
{
try
{
loadPlugin(skinPluginPath, pkgName, suffix);
} catch (Exception e)
{
e.printStackTrace();
skinChangingCallback.onError(e);
}
return null;
}
@Override
protected void onPostExecute(Void aVoid)
{
try
{
updatePluginInfo(skinPluginPath, pkgName, suffix);
notifyChangedListeners();
skinChangingCallback.onComplete();
} catch (Exception e)
{
e.printStackTrace();
skinChangingCallback.onError(e);
}
}
}.execute();
}
public void addSkinView(ISkinChangedListener listener, List<SkinView> skinViews)
{
mSkinViewMaps.put(listener, skinViews);
}
public List<SkinView> getSkinViews(ISkinChangedListener listener)
{
return mSkinViewMaps.get(listener);
}
public void apply(ISkinChangedListener listener)
{
List<SkinView> skinViews = getSkinViews(listener);
if (skinViews == null) return;
for (SkinView skinView : skinViews)
{
skinView.apply();
}
}
public void addChangedListener(ISkinChangedListener listener)
{
mSkinChangedListeners.add(listener);
}
public void removeChangedListener(ISkinChangedListener listener)
{
mSkinChangedListeners.remove(listener);
mSkinViewMaps.remove(listener);
}
public void notifyChangedListeners()
{
for (ISkinChangedListener listener : mSkinChangedListeners)
{
listener.onSkinChanged();
}
}
}