搭建项目基础框架

    技术2022-07-10  145

    一、设计全局配置器

    依照“单例模式”下的“懒汉式”,通过枚举类和静态内部类来实现,保证线程安全,也避免使用双重校验锁。

    1. public class Configurator

    该类用于配置文件的存储和获取,包括各种配置项(如,后端主机地址)、字体图标库的引用、用于线程通信的全局Handler。

    import android.os.Handler; import com.blankj.utilcode.util.Utils; import com.joanzapata.iconify.IconFontDescriptor; import com.joanzapata.iconify.Iconify; import java.util.ArrayList; import java.util.HashMap; public class Configurator { private static final HashMap<Object,Object> QILU_CONFIGS= new HashMap<>(); private static final Handler HANDLER = new Handler(); private static final ArrayList<IconFontDescriptor> ICONS = new ArrayList<>(); // 不让其他类创建本类的对象 private Configurator(){ QILU_CONFIGS.put(ConfigKeys.CONFIG_READY, false); QILU_CONFIGS.put(ConfigKeys.HANDLER, HANDLER); } //利用静态内部类进行初始化 private static class Holder { private static final Configurator INSTANCE = new Configurator(); } static Configurator getInstance() { return Holder.INSTANCE; } final HashMap<Object, Object> getQiluConfigs() { return QILU_CONFIGS; } public final void configure() { initIcons(); QILU_CONFIGS.put(ConfigKeys.CONFIG_READY, true); Utils.init(Qilu.getApplicationContext()); } private void initIcons() { if (ICONS.size() > 0) { final Iconify.IconifyInitializer initializer = Iconify.with(ICONS.get(0)); for (int i = 1; i < ICONS.size(); i++) { initializer.with(ICONS.get(i)); } } } public final Configurator withIcon(IconFontDescriptor descriptor) { ICONS.add(descriptor); return this; } public final Configurator withApiHost(String host) { QILU_CONFIGS.put(ConfigKeys.API_HOST, host); return this; } public final Configurator withLoaderDelayed(long delayed) { QILU_CONFIGS.put(ConfigKeys.LOADER_DELAYED, delayed); return this; } private void checkConfiguration() { final boolean isReady = (boolean) QILU_CONFIGS.get(ConfigKeys.CONFIG_READY); if (!isReady) { throw new RuntimeException("Configuration is not ready,call configure"); } } @SuppressWarnings("unchecked") final <T> T getConfiguration(Object key) { checkConfiguration(); final Object value = QILU_CONFIGS.get(key); if (value == null) { throw new NullPointerException(key.toString() + " IS NULL"); } return (T) QILU_CONFIGS.get(key); } }

    2. public final class Qilu

    该类仅仅是对外提供操作的工具类,全部是静态方法。

    import android.content.Context; import android.os.Handler; public final class Qilu { //初始化 public static Configurator init(Context context) { Configurator.getInstance() .getQiluConfigs() .put(ConfigKeys.APPLICATION_CONTEXT, context.getApplicationContext()); return Configurator.getInstance(); } public static Configurator getConfigurator() { return Configurator.getInstance(); } public static <T> T getConfiguration(Object key) { return getConfigurator().getConfiguration(key); } public static Context getApplicationContext() { return getConfiguration(ConfigKeys.APPLICATION_CONTEXT); } public static Handler getHandler() { return getConfiguration(ConfigKeys.HANDLER); } }

    二、字体图标库的集成

    App使用字体图标库来代替许多图片。 App使用很多图片有许多缺陷:App体积过大;屏幕分辨率变化时,图片很难保持高保真。 App使用字体图标库,可以显著减小App的体积,因为字体图标可以实时渲染,无需大量静态存储空间。App使用字体图标,即便屏幕分辨率大幅变化,字体图标也不会失真,因为字体图标基于SVG(可缩放的矢量图形)。

    1. 添加依赖

    GitHub链接:android-iconify 在core模块的build.gradle中添加以下内容:

    api 'com.joanzapata.iconify:android-iconify-fontawesome:2.2.2' api 'com.joanzapata.iconify:android-iconify-entypo:2.2.2' api 'com.joanzapata.iconify:android-iconify-typicons:2.2.2' api 'com.joanzapata.iconify:android-iconify-material:2.2.2' api 'com.joanzapata.iconify:android-iconify-material-community:2.2.2' api 'com.joanzapata.iconify:android-iconify-meteocons:2.2.2' api 'com.joanzapata.iconify:android-iconify-weathericons:2.2.2' api 'com.joanzapata.iconify:android-iconify-simplelineicons:2.2.2' api 'com.joanzapata.iconify:android-iconify-ionicons:2.2.2'

    同步项目

    2. 在Configurator中添加初始化方法

    private static final ArrayList<IconFontDescriptor> ICONS = new ArrayList<>(); public final Configurator withIcon(IconFontDescriptor descriptor) { ICONS.add(descriptor); return this; } private void initIcons() { if (ICONS.size() > 0) { final Iconify.IconifyInitializer initializer = Iconify.with(ICONS.get(0)); for (int i = 1; i < ICONS.size(); i++) { initializer.with(ICONS.get(i)); } } }

    三、基础框架可用性验证

    验证所搭建的基础框架是否生效

    1. 主Application中执行初始化操作

    import android.app.Application; import com.joanzapata.iconify.fonts.EntypoModule; import com.joanzapata.iconify.fonts.FontAwesomeModule; import com.joanzapata.iconify.fonts.IoniconsModule; import com.joanzapata.iconify.fonts.MaterialCommunityModule; import com.joanzapata.iconify.fonts.MaterialModule; import com.joanzapata.iconify.fonts.MeteoconsModule; import com.joanzapata.iconify.fonts.SimpleLineIconsModule; import com.joanzapata.iconify.fonts.TypiconsModule; import com.joanzapata.iconify.fonts.WeathericonsModule; import com.qilu.core.app.Qilu; public class MainApp extends Application { @Override public void onCreate() { super.onCreate(); Qilu.init(this) .withIcon(new FontAwesomeModule()) .withIcon(new EntypoModule()) .withIcon(new TypiconsModule()) .withIcon(new MaterialModule()) .withIcon(new MaterialCommunityModule()) .withIcon(new MeteoconsModule()) .withIcon(new WeathericonsModule()) .withIcon(new SimpleLineIconsModule()) .withIcon(new IoniconsModule()) .withApiHost("http://106.13.96.60:8888/") .withLoaderDelayed(3000) .configure(); } }

    2. 在测试页面中查看效果

    在测试页面的布局文件中使用了字体图标

    <com.joanzapata.iconify.widget.IconTextView android:text="I {fa-heart-o} to {fa-code} on {fa-android}" android:shadowColor="#22000000" android:shadowDx="3" android:shadowDy="3" android:shadowRadius="1" android:textSize="40sp" android:textColor="#FF..." ... />

    运行结果

    Processed: 0.009, SQL: 9