文末
js前端的重头戏,值得花大部分时间学习。
推荐通过书籍学习,《 JavaScript 高级程序设计(第 4 版)》你值得拥有。整本书内容质量都很高,尤其是前十章语言基础部分,建议多读几遍。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
另外,大推一个网上教程 现代 JavaScript 教程 ,文章深入浅出,很容易理解,上面的内容几乎都是重点,而且充分发挥了网上教程的时效性和资料链接。
学习资料在精不在多,二者结合,定能构建你的 JavaScript 知识体系。
面试本质也是考试,面试题就起到很好的考纲作用。想要取得优秀的面试成绩,刷面试题是必须的,除非你样样精通。
这是288页的前端面试题
随着我们业务的增加,我们的包体积越来越大,包体积越小对于咱们app的转化率越高,这章节讲一下图片的统一处理逻辑。占用包体积的最大的因素
- so文件,使用动态加载so,不把so打包在包内,请参考动态加载so
- 图片的处理,使用aop思想处理本app、第三方aar以及第三方jar中的图片,本节的内容
二。一些减少包体积的方法
- 压缩代码,移除未使用的资源 。使用ProGuard进行压缩
- 减少枚举使用
- 精简语言资源
- 使用矢量图
- 仅支持特定密度
- 资源混淆 AndroidResGuard
- R文件内联 Bytex
- 插件化
三。写一个压缩图片以及把png和jpg转化成webp的插件
首先我们思考一下怎样可以实现这个功能
- 怎样拿到统一的图片?
- 使用什么工具或者代码去压缩?
- 怎样把压缩完成之后的图片转化成webp?
- 什么图片不能压缩以及转化webp?
基于问题一:我们可以在打包apk的task中寻找答案,我们可以在mergeResources的task的时候拿过来输入文件。 来拿到所有的图片进行压缩,具体的打包task可以参考 补齐Android技能树——从AGP构建过程到APK打包过程 , 另一个从gradle 4之后的 com.android.build.gradle.internal.AbstractAppTaskManager.java中的createCommonTasks 方法也可以看的出来。
基于问题二: 压缩png可以使用pngcrush、pngquant 或 zopflipng ,压缩jpg可以使用 packJPG 和 guetzli
基于问题三: 使用google为咱们提供的cwebp来进行转化
基于问题四:一些logo,还有转化之后变大的都不不哟用转
开始撸代码
创建plugin工程
首先创建一个plugin工程,在主项目创建buildSrc目录,在创建src/main文件夹,在main中创建 resources ,用来标记咱们的插件,在resources中创建 META-INF/gradle-plugins 文件夹,在创建 com.nzy.plugin.properties 的配置文件,里面配置咱们的plugin ,implementation-class=com.nzy.plugin.CwebpPlugin,
创建java的plugin CwebpPlugin类
public class CwebpPlugin implements Plugin {
int oldSize = 0;
int newSize = 0;
public static final String TAG = “CwebpPlugin :”;
/**
- 用户config的配置
*/
private WebpConfig mConfig;
/**
- 打印日志
*/
private Logger mLogger;
private ArrayList bigImgList = new ArrayList();
private Project mProject;
private AppExtension mAppExtension;
private ArrayList cacheList = new ArrayList();
/**
- 所有图片的文件
*/
private ArrayList imageFileList = new ArrayList();
@Override
public void apply(Project project) {
if (!project.getPlugins().hasPlugin(AppPlugin.class)) {
throw new GradleException(“必须在android application插件中使用改插件”);
}
//得到android的配置
mAppExtension = project.getExtensions().getByType(AppExtension.class);
// 创建 WebpConfig 的扩展,使用户可以在build.gradle中使用
project.getExtensions().create(“webpConfig”, WebpConfig.class);
mProject = project;
mLogger = project.getLogger();
LoggerUtil.sLogger = mLogger;
printAllTask();
convertTask();
}
/**
- 开始转化
*/
private void convertTask() {
//就和引入了 apply plugin: ‘com.android.application’ 一样,可以配置android{}
//gradle执行会解析build.gradle文件,afterEvaluate表示在解析完成之后再执行我们的代码
mProject.afterEvaluate(new Action() {
@Override
public void execute(@NotNull Project project) {
initConfig();
}
});
}
/**
- 拿到用户的配置
*/
private void initConfig() {
mConfig = mProject.getExtensions().findByType(WebpConfig.class);
int quality = mConfig.quality;
ArrayList whiteList = mConfig.whiteList;
boolean debugOn = mConfig.debugOn;
mLogger.log(LogLevel.ERROR, TAG + “config的质量是:” + quality + " 白名单是" + Arrays.toString(whiteList.toArray()) + " debug模式时是否开启:" + debugOn);
// android项目默认会有 debug和release,
// 那么getApplicationVariants就是包含了debug和release的集合,all表示对集合进行遍历
mAppExtension.getApplicationVariants().all(new Action() {
@Override
public void execute(ApplicationVariant applicationVariant) {
//当前用户是debug模式,并且没有配置debug运行执行热修复
if (applicationVariant.getName().contains(“debug”) && !debugOn) {
return;
}
//开始压缩等一些列的
convert(applicationVariant);
}
});
}
private void convert(ApplicationVariant variant) {
//获得: debug/release
String variantName = variant.getName();
//首字母大写
String capitalizeName = Utils.capitalize(variantName);
// 这是项目的根路径
String rootPath = mProject.getRootDir().getPath();
// 这是 cwebp 工具的地址
FileUtil.TOOLS_DIRPATH = rootPath + “/mctools/”;
// 第一种拿到资源
getRes1(capitalizeName);
// 第二种拿到资源
//getRes2(variant, capitalizeName);
// 第三种拿到资源
//getRes3(variant);
}
/**
- 第一种拿到资源的方法
- @param capitalizeName
*/
private void getRes1(String capitalizeName) {
// 获得android的mergeDebugResources/mergeReleaseResources任务
final Task mergeResTask =
mProject.getTasks().findByName(“merge” + capitalizeName + “Resources”);
if (mergeResTask != null) {
imageFileList.clear();
cacheList.clear();
mergeResTask.doFirst(new Action() {
@Override
public void execute(Task task) {
//资源输出的所有文件
TaskInputs outputs = mergeResTask.getInputs();
Set files = outputs.getFiles().getFiles();
for (File file : files) {
// 遍历文件夹 拿到 所有的 图片
traverseDir(file);
}
// 开始压缩
startConvertAndCompress();
}
});
}
}
/**
- 处理图片压缩任务
*/
private void startConvertAndCompress() {
if (imageFileList.isEmpty()) {
return;
}
for (File file : imageFileList) {
// 压缩
CompressUtil.compressImg(file, mProject);
// 转化webp
ConvertWebpUtil.securityFormatWebp(file, mConfig, mProject, mLogger);
}
}
❤️ 谢谢支持
喜欢的话别忘了 关注、点赞哦~。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
Config, mProject, mLogger);
}
}
❤️ 谢谢支持
喜欢的话别忘了 关注、点赞哦~。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
[外链图片转存中…(img-ocbMSQec-1715886618929)]