Created
May 9, 2018 10:58
-
-
Save shaobin0604/877b66172fe3683995318ae6b99f7e04 to your computer and use it in GitHub Desktop.
ArtDexOptimizer.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.lody.virtual.helper; | |
import android.os.Build; | |
import java.io.File; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.concurrent.Executor; | |
import java.util.concurrent.Executors; | |
import mirror.dalvik.system.VMRuntime; | |
/** | |
* @author Lody | |
*/ | |
public class ArtDexOptimizer { | |
/** | |
* Optimize the dex in interpret mode. | |
* | |
* @param dexFilePath dex file path | |
* @param oatFilePath oat file path | |
* @throws IOException | |
*/ | |
public static void interpretDex2Oat(String dexFilePath, String oatFilePath) throws IOException { | |
final File oatFile = new File(oatFilePath); | |
if (!oatFile.exists()) { | |
oatFile.getParentFile().mkdirs(); | |
} | |
final List<String> commandAndParams = new ArrayList<>(); | |
commandAndParams.add("dex2oat"); | |
// for 7.1.1, duplicate class fix | |
if (Build.VERSION.SDK_INT >= 24) { | |
commandAndParams.add("--runtime-arg"); | |
commandAndParams.add("-classpath"); | |
commandAndParams.add("--runtime-arg"); | |
commandAndParams.add("&"); | |
} | |
commandAndParams.add("--dex-file=" + dexFilePath); | |
commandAndParams.add("--oat-file=" + oatFilePath); | |
commandAndParams.add("--instruction-set=" + VMRuntime.getCurrentInstructionSet.call()); | |
if (Build.VERSION.SDK_INT > 25) { | |
commandAndParams.add("--compiler-filter=quicken"); | |
} else { | |
commandAndParams.add("--compiler-filter=interpret-only"); | |
} | |
final ProcessBuilder pb = new ProcessBuilder(commandAndParams); | |
pb.redirectErrorStream(true); | |
final Process dex2oatProcess = pb.start(); | |
StreamConsumer.consumeInputStream(dex2oatProcess.getInputStream()); | |
StreamConsumer.consumeInputStream(dex2oatProcess.getErrorStream()); | |
try { | |
final int ret = dex2oatProcess.waitFor(); | |
if (ret != 0) { | |
throw new IOException("dex2oat works unsuccessfully, exit code: " + ret); | |
} | |
} catch (InterruptedException e) { | |
throw new IOException("dex2oat is interrupted, msg: " + e.getMessage(), e); | |
} | |
} | |
private static class StreamConsumer { | |
static final Executor STREAM_CONSUMER = Executors.newSingleThreadExecutor(); | |
static void consumeInputStream(final InputStream is) { | |
STREAM_CONSUMER.execute(new Runnable() { | |
@Override | |
public void run() { | |
if (is == null) { | |
return; | |
} | |
final byte[] buffer = new byte[256]; | |
try { | |
while ((is.read(buffer)) > 0) { | |
// To satisfy checkstyle rules. | |
} | |
} catch (IOException ignored) { | |
// Ignored. | |
} finally { | |
try { | |
is.close(); | |
} catch (Exception ignored) { | |
// Ignored. | |
} | |
} | |
} | |
}); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment