From 74225399ad53b33bc607f1b676f75e5de578b397 Mon Sep 17 00:00:00 2001 From: guidongqi Date: Sun, 10 Nov 2019 16:05:39 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8E=BB=E9=99=A4=E5=BC=BA=E5=88=B6?= =?UTF-8?q?=E9=87=8D=E5=86=99attachBaseContext=E6=96=B9=E6=B3=95=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 22 ++++++++++++ README.md | 16 +++++++++ app/build.gradle | 3 +- build.gradle | 6 ++-- gradle.properties | 2 +- plugin/build.gradle | 3 ++ .../plugin/MultiLanguagesTransform.groovy | 27 ++++++++------ .../plugin/PluginExtension.groovy | 3 ++ .../plugin/ActivityServiceClassVisitor.java | 35 +++++++++++++++++-- 9 files changed, 100 insertions(+), 17 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..1bcbedd --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,22 @@ +## CHANGELOG + +### v0.0.7 +- 去除强制覆盖重写```attachBaseContext```方法逻辑。 + + - 如果类里原来重写了该方法需要手动加上 + + ``` super.attachBaseContext(MultiLanguage.setLocal(newBase));```, + + - 或者在插件配置里```overwriteClass```里加上全路径包名后插件覆盖重写 + + ``` + multiLanguages { + enable = true + overwriteClass = ["com.github.jokar.multilanguages.BaseActivity"] + } + ``` + +### v0.0.6 +- 支持androidx +- 支持androidx-v1.1.0版本 + diff --git a/README.md b/README.md index 50bc852..1a8b3c3 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,22 @@ 以上就完成了初始化了, +### ```attachBaseContext```方法已被重写过 +在v0.0.7版本去除了强制重写```attachBaseContext```方法的逻辑,如果类里原来重写了该方法需要手动加上 + +``` super.attachBaseContext(MultiLanguage.setLocal(newBase));``` + +如果需要强制重写可以在在插件配置里```overwriteClass```里加上全路径包名后插件覆盖重写 + +``` + multiLanguages { + enable = true + overwriteClass = ["com.github.jokar.multilanguages.BaseActivity"] + } +``` +### locales列表 + +https://github.com/championswimmer/android-locales ### 博客 [多语言实现](https://blog.csdn.net/a1018875550/article/details/79845949) diff --git a/app/build.gradle b/app/build.gradle index 90a60d4..4688454 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,9 +28,10 @@ dependencies { implementation 'com.android.support:appcompat-v7:27.1.1' implementation 'com.android.support.constraint:constraint-layout:1.1.3' testImplementation 'junit:junit:4.12' - implementation "com.github.jokar:multi-languages:$version" + implementation "com.github.jokar:multi-languages:0.0.7" } multiLanguages { enable = true + overwriteClass = ["com.github.jokar.multilanguages.BaseActivity"] } \ No newline at end of file diff --git a/build.gradle b/build.gradle index adbc957..ae85640 100644 --- a/build.gradle +++ b/build.gradle @@ -7,12 +7,11 @@ buildscript { jcenter() mavenCentral() maven {url 'https://dl.bintray.com/a10188755550/maven'} - } dependencies { classpath 'com.android.tools.build:gradle:3.5.2' classpath 'com.novoda:bintray-release:0.9.1' - classpath "com.github.jokar:multi-languages.plugin:$version" + classpath "com.github.jokar:multi-languages.plugin:0.0.7" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } @@ -37,4 +36,7 @@ tasks.withType(Javadoc) { charSet 'UTF-8' links "http://docs.oracle.com/javase/7/docs/api" } +} +configurations.all { + resolutionStrategy.cacheChangingModulesFor 0, 'seconds' } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 1cb8512..2035b6f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,4 +13,4 @@ org.gradle.jvmargs=-Xmx1536m # org.gradle.parallel=true android.enableD8=true -version=0.0.6 \ No newline at end of file +version=0.0.7 \ No newline at end of file diff --git a/plugin/build.gradle b/plugin/build.gradle index 1cd9f62..7f89a32 100644 --- a/plugin/build.gradle +++ b/plugin/build.gradle @@ -25,3 +25,6 @@ publish { desc = 'android multi language support (support android O+)' website = 'https://github.com/MichaelJokAr/MultiLanguages' } + + +apply from: 'maven.gradle' \ No newline at end of file diff --git a/plugin/src/main/groovy/com/github/jokar/multilanguages/plugin/MultiLanguagesTransform.groovy b/plugin/src/main/groovy/com/github/jokar/multilanguages/plugin/MultiLanguagesTransform.groovy index c6602ec..4bcd62a 100644 --- a/plugin/src/main/groovy/com/github/jokar/multilanguages/plugin/MultiLanguagesTransform.groovy +++ b/plugin/src/main/groovy/com/github/jokar/multilanguages/plugin/MultiLanguagesTransform.groovy @@ -8,6 +8,7 @@ import org.apache.commons.io.FileUtils import org.apache.commons.io.IOUtils import org.objectweb.asm.ClassReader import org.objectweb.asm.ClassWriter +import org.slf4j.LoggerFactory import java.util.jar.JarEntry import java.util.jar.JarFile @@ -16,6 +17,7 @@ import java.util.zip.ZipEntry class MultiLanguagesTransform extends Transform { private PluginExtension pluginExtension + def static slf4jLogger = LoggerFactory.getLogger('logger') MultiLanguagesTransform(PluginExtension pluginExtension) { this.pluginExtension = pluginExtension @@ -93,7 +95,7 @@ class MultiLanguagesTransform extends Transform { if (checkClassFile(name)) { def classReader = new ClassReader(file.bytes) def classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS) - def cv = new ActivityServiceClassVisitor(classWriter) + def cv = new ActivityServiceClassVisitor(classWriter, pluginExtension.overwriteClass) classReader.accept(cv, ClassReader.EXPAND_FRAMES) //添加方法 addAttachMethod(cv, name, classWriter) @@ -122,14 +124,19 @@ class MultiLanguagesTransform extends Transform { */ private static void addAttachMethod(ActivityServiceClassVisitor cv, name, ClassWriter classWriter) { if (cv.needAddAttach()) { - println("add attach method to ${name}") - //添加attachBaseContext方法 - if (cv.activity) { - MethodVisitorUtil.addActivityAttach(classWriter) - } else if (cv.service) { - MethodVisitorUtil.addServiceAttach(classWriter) - } else if (cv.intentService) { - MethodVisitorUtil.addIntentServiceAttach(classWriter) + if (cv.shouldOverwriteAttachMethod) { + println("add attach method to ${name}") + //添加attachBaseContext方法 + if (cv.activity) { + MethodVisitorUtil.addActivityAttach(classWriter) + } else if (cv.service) { + MethodVisitorUtil.addServiceAttach(classWriter) + } else if (cv.intentService) { + MethodVisitorUtil.addIntentServiceAttach(classWriter) + } + } else { + slf4jLogger.error("skip ${name}, you should overwrite attachBaseContext by your self, " + + "or you can add this full class name to plugin extension.overwriteClass") } //添加applyOverrideConfiguration方法 if (cv.needAddACMethod()) { @@ -171,7 +178,7 @@ class MultiLanguagesTransform extends Transform { jarOutputStream.putNextEntry(zipEntry) def classReader = new ClassReader(IOUtils.toByteArray(inputStream)) def classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS) - def cv = new ActivityServiceClassVisitor(classWriter) + def cv = new ActivityServiceClassVisitor(classWriter, pluginExtension.overwriteClass) classReader.accept(cv, ClassReader.EXPAND_FRAMES) // addAttachMethod(cv, entryName, classWriter) diff --git a/plugin/src/main/groovy/com/github/jokar/multilanguages/plugin/PluginExtension.groovy b/plugin/src/main/groovy/com/github/jokar/multilanguages/plugin/PluginExtension.groovy index 65542ee..a65f95e 100644 --- a/plugin/src/main/groovy/com/github/jokar/multilanguages/plugin/PluginExtension.groovy +++ b/plugin/src/main/groovy/com/github/jokar/multilanguages/plugin/PluginExtension.groovy @@ -2,11 +2,14 @@ package com.github.jokar.multilanguages class PluginExtension { boolean enable = true + List overwriteClass = new ArrayList<>() + @Override String toString() { return "PluginExtension{" + "enable=" + enable + + ", overwriteClass=" + overwriteClass.toString() + '}' } } \ No newline at end of file diff --git a/plugin/src/main/java/com/github/jokar/multilanguages/plugin/ActivityServiceClassVisitor.java b/plugin/src/main/java/com/github/jokar/multilanguages/plugin/ActivityServiceClassVisitor.java index e4b756a..b92af5b 100644 --- a/plugin/src/main/java/com/github/jokar/multilanguages/plugin/ActivityServiceClassVisitor.java +++ b/plugin/src/main/java/com/github/jokar/multilanguages/plugin/ActivityServiceClassVisitor.java @@ -5,6 +5,8 @@ import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; +import java.util.List; + /** * Create by JokAr. on 2019-07-08. */ @@ -15,9 +17,12 @@ public class ActivityServiceClassVisitor extends ClassVisitor implements Opcodes * 是否有applyOverrideConfiguration方法 */ private boolean hasACMethod; + private boolean shouldOverwriteAttachMethod = true; + private List overwriteClass; - public ActivityServiceClassVisitor(ClassWriter cv) { + public ActivityServiceClassVisitor(ClassWriter cv, List overwriteClass) { super(Opcodes.ASM5, cv); + this.overwriteClass = overwriteClass; } @Override @@ -34,8 +39,13 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str if (needAddAttach()) { hasACMethod = name.equals("applyOverrideConfiguration"); if (name.equals("attachBaseContext")) { - //删除原有 attachBaseContext 方法 - return null; + if (showOverwriteAttachMethod()) { + shouldOverwriteAttachMethod = true; + //删除原有 attachBaseContext 方法 + return null; + } else { + shouldOverwriteAttachMethod = false; + } } else if (isAndroidxActivity() && name.equals("applyOverrideConfiguration")) { //是继承androidx.AppCompatActivity的activity,在 applyOverrideConfiguration //添加 overrideConfiguration.setTo(this.getBaseContext().getResources().getConfiguration()); @@ -120,4 +130,23 @@ public boolean isIntentService() { public String getClassName() { return className; } + + /** + * 是否强制覆盖重写attach方法 + * + * @return + */ + private boolean showOverwriteAttachMethod() { + for (String clazz : overwriteClass) { + String clazzName = clazz.replaceAll("\\.","\\/"); + if (clazzName.equals(className)) { + return true; + } + } + return false; + } + + public boolean isShouldOverwriteAttachMethod() { + return shouldOverwriteAttachMethod; + } }