From c02bf30cc78a4109bb2a22cd7b6278430fba5585 Mon Sep 17 00:00:00 2001 From: TonyJiangWJ Date: Sat, 8 Jan 2022 02:21:28 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../autojs/timing/TimedTaskScheduler.java | 12 +++-- .../stardust/autojs/core/looper/Loopers.java | 5 +- .../autojs/rhino/AndroidClassLoader.java | 53 ++++++++++++++----- 3 files changed, 52 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/org/autojs/autojs/timing/TimedTaskScheduler.java b/app/src/main/java/org/autojs/autojs/timing/TimedTaskScheduler.java index 1294e504..ea5d7cdd 100644 --- a/app/src/main/java/org/autojs/autojs/timing/TimedTaskScheduler.java +++ b/app/src/main/java/org/autojs/autojs/timing/TimedTaskScheduler.java @@ -57,6 +57,7 @@ public class TimedTaskScheduler { /** * only available in WorkManagerProvider and AndroidJobProvider + * * @param context * @param timedTask * @param millis @@ -123,16 +124,19 @@ public class TimedTaskScheduler { public static WorkProvider getWorkProvider(Context context) { try { - PreferenceManager.getDefaultSharedPreferences(context).getString(WorkProviderConstants.ACTIVE_PROVIDER, WorkProviderConstants.ALARM_MANAGER_PROVIDER); + // 尝试获取默认的类型 失败后设置ALARM_MANAGER作为默认的 + PreferenceManager.getDefaultSharedPreferences(context).getString(WorkProviderConstants.ACTIVE_PROVIDER, + WorkProviderConstants.ALARM_MANAGER_PROVIDER); } catch (Exception e) { - PreferenceManager.getDefaultSharedPreferences(context).edit().putString(WorkProviderConstants.ACTIVE_PROVIDER, WorkProviderConstants.ALARM_MANAGER_PROVIDER).apply(); + PreferenceManager.getDefaultSharedPreferences(context).edit().putString(WorkProviderConstants.ACTIVE_PROVIDER, + WorkProviderConstants.ALARM_MANAGER_PROVIDER).apply(); } String currentActive = PreferenceManager.getDefaultSharedPreferences(context) - .getString(WorkProviderConstants.ACTIVE_PROVIDER, WorkProviderConstants.WORK_MANAGER_PROVIDER); + .getString(WorkProviderConstants.ACTIVE_PROVIDER, WorkProviderConstants.ALARM_MANAGER_PROVIDER); if (WorkProviderConstants.WORK_MANAGER_PROVIDER.equals(currentActive)) { Log.d(LOG_TAG, "当前启用的定时任务方式为WorkManager"); return WorkManagerProvider.getInstance(context); - } else if (WorkProviderConstants.ANDROID_JOB_PROVIDER.equals(currentActive)){ + } else if (WorkProviderConstants.ANDROID_JOB_PROVIDER.equals(currentActive)) { Log.d(LOG_TAG, "当前启用的定时任务方式为AndroidJob"); return AndroidJobProvider.getInstance(context); } else { diff --git a/autojs/src/main/java/com/stardust/autojs/core/looper/Loopers.java b/autojs/src/main/java/com/stardust/autojs/core/looper/Loopers.java index 2af04c29..25b4b6e2 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/looper/Loopers.java +++ b/autojs/src/main/java/com/stardust/autojs/core/looper/Loopers.java @@ -186,15 +186,16 @@ public class Loopers implements MessageQueue.IdleHandler { if (l == null) return true; if (l == mMainLooper) { - Log.d(LOG_TAG, "main looper queueIdle"); +// Log.d(LOG_TAG, "main looper queueIdle"); if (shouldQuitLooper() && !mThreads.hasRunningThreads() && mMainLooperQuitHandler != null && mMainLooperQuitHandler.shouldQuit()) { Log.d(LOG_TAG, "main looper quit"); l.quit(); } } else { - Log.d(LOG_TAG, "looper queueIdle: " + l); +// Log.d(LOG_TAG, "looper queueIdle: " + l); if (shouldQuitLooper()) { + Log.d(LOG_TAG, "looper quit"); l.quit(); } } diff --git a/autojs/src/main/java/com/stardust/autojs/rhino/AndroidClassLoader.java b/autojs/src/main/java/com/stardust/autojs/rhino/AndroidClassLoader.java index 1b066e25..ffe93ed9 100644 --- a/autojs/src/main/java/com/stardust/autojs/rhino/AndroidClassLoader.java +++ b/autojs/src/main/java/com/stardust/autojs/rhino/AndroidClassLoader.java @@ -1,8 +1,6 @@ package com.stardust.autojs.rhino; -import java.util.WeakHashMap; - -import android.util.Log; +import android.os.Build; import com.android.dx.command.dexer.Main; import com.stardust.pio.PFiles; @@ -13,18 +11,24 @@ import net.lingala.zip4j.exception.ZipException; import net.lingala.zip4j.model.FileHeader; import net.lingala.zip4j.model.ZipParameters; +import org.apache.log4j.Logger; import org.mozilla.javascript.GeneratedClassLoader; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; +import java.util.Base64; import java.util.LinkedHashMap; import java.util.List; import java.util.ListIterator; import java.util.Map; +import java.util.WeakHashMap; +import androidx.annotation.RequiresApi; import dalvik.system.DexClassLoader; /** @@ -39,6 +43,7 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa private final Map mDexClassLoaders = new LinkedHashMap<>(); private final File mCacheDir; private final File mLibsDir; + private Logger logger = Logger.getLogger(AndroidClassLoader.class); private final WeakHashMap weakDexFileMap = new WeakHashMap<>(); @@ -67,7 +72,7 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa */ @Override public Class defineClass(String name, byte[] data) { - Log.d(LOG_TAG, "defineClass: name = " + name + " data.length = " + data.length); + logger.debug("defineClass: name = " + name + " data.length = " + data.length); File classFile = null; try { classFile = generateTempFile(name, false); @@ -75,7 +80,9 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa final ZipParameters parameters = new ZipParameters(); parameters.setFileNameInZip(name.replace('.', '/') + ".class"); parameters.setSourceExternalStream(true); - zipFile.addStream(new ByteArrayInputStream(data), parameters); + ByteArrayInputStream is = new ByteArrayInputStream(data); + zipFile.addStream(is, parameters); + is.close(); return dexJar(classFile, null).loadClass(name); } catch (IOException | ZipException | ClassNotFoundException e) { throw new FatalLoadingException(e); @@ -87,7 +94,7 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa } private File generateTempFile(String name, boolean create) throws IOException { - File file = new File(mCacheDir, name.hashCode() + System.currentTimeMillis() + ".jar"); + File file = new File(mCacheDir, name.hashCode() + "_" + System.currentTimeMillis() + ".jar"); if (create) { if (!file.exists()) { file.createNewFile(); @@ -99,7 +106,7 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa } public void loadJar(File jar) throws IOException { - Log.d(LOG_TAG, "loadJar: jar = " + jar); + logger.debug("loadJar: jar = " + jar); if (!jar.exists() || !jar.canRead()) { throw new FileNotFoundException("File does not exist or readable: " + jar.getPath()); } @@ -134,11 +141,11 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa } public DexClassLoader loadDex(File file) throws FileNotFoundException { - Log.d(LOG_TAG, "loadDex: file = " + file); + logger.debug("loadDex: file = " + file); if (!file.exists()) { throw new FileNotFoundException(file.getPath()); } - Log.d(LOG_TAG, "dex file size: " + file.length()); + logger.debug("dex file size: " + file.length()); DexClassLoader loader = new DexClassLoader(file.getPath(), mCacheDir.getPath(), mLibsDir.getPath(), parent); // 根据dex文件名 移除已有的,使得最新载入的在LinkedHashMap末尾 mDexClassLoaders.remove(file.getName()); @@ -169,18 +176,40 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa } arguments.outName = dexFile.getPath(); arguments.jarOutput = true; + arguments.verbose = true; Main.run(arguments); - Log.d(LOG_TAG, "dex file size: " + dexFile.length()); + logger.debug("dex file size: " + dexFile.length()); + if (dexFile.length() == 0) { + // 出现了异常 + logger.error("创建dex文件失败,class文件路径:" + classFile.getPath() + " 大小:" + classFile.length()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + dumpClassfileIntoLog(classFile); + } + } DexClassLoader loader = loadDex(dexFile); if (isTmpDex) { - Log.d(LOG_TAG, "delete tmpFile on finalize:" + dexFile.getName()); + logger.debug("delete tmpFile on finalize:" + dexFile.getName()); // 当弱引用失去引用时 删除File对象 weakDexFileMap.put(new DeleteOnFinalizeFile(dexFile), dexFile.getName()); - Log.d(LOG_TAG, "current weakMap size:" + weakDexFileMap.size()); + logger.debug("current weakMap size:" + weakDexFileMap.size()); } return loader; } + @RequiresApi(api = Build.VERSION_CODES.O) + private void dumpClassfileIntoLog(File classFile) { + try ( + FileInputStream fis = new FileInputStream(classFile); + ) { + byte[] buff = new byte[(int) classFile.length()]; + fis.read(buff); + String base64 = Base64.getEncoder().encodeToString(buff); + logger.debug("class file content base64:" + base64); + } catch (Exception e) { + logger.error("备份class文件异常", e); + } + } + /** * Does nothing *