Google a ajouté un nouveau ART runtime avec Android 4.4. Comment puis-je déterminer si ART ou Dalvik est le runtime actuel?
Au moins, dès juin 2014, Google a publié une documentation officielle sur comment vérifier correctement le runtime en cours d'utilisation :
Vous pouvez vérifier quel runtime est utilisé en appelant System.getProperty ("Java.vm.version"). Si ART est utilisé, la valeur de la propriété est "2.0.0" ou supérieure.
Avec cela, il n'est plus nécessaire de passer par la réflexion et de simplement vérifier la propriété système correspondante:
private boolean getIsArtInUse() {
final String vmVersion = System.getProperty("Java.vm.version");
return vmVersion != null && vmVersion.startsWith("2");
}
Une façon possible est de lire les SystemProperty
respectifs par réflexion.
Échantillon:
package com.example.getcurrentruntimevalue;
import Android.app.Activity;
import Android.os.Bundle;
import Android.widget.TextView;
import Java.lang.reflect.InvocationTargetException;
import Java.lang.reflect.Method;
public class MainActivity extends Activity {
private static final String SELECT_RUNTIME_PROPERTY = "persist.sys.dalvik.vm.lib";
private static final String LIB_DALVIK = "libdvm.so";
private static final String LIB_ART = "libart.so";
private static final String LIB_ART_D = "libartd.so";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView)findViewById(R.id.current_runtime_value);
tv.setText(getCurrentRuntimeValue());
}
private CharSequence getCurrentRuntimeValue() {
try {
Class<?> systemProperties = Class.forName("Android.os.SystemProperties");
try {
Method get = systemProperties.getMethod("get",
String.class, String.class);
if (get == null) {
return "WTF?!";
}
try {
final String value = (String)get.invoke(
systemProperties, SELECT_RUNTIME_PROPERTY,
/* Assuming default is */"Dalvik");
if (LIB_DALVIK.equals(value)) {
return "Dalvik";
} else if (LIB_ART.equals(value)) {
return "ART";
} else if (LIB_ART_D.equals(value)) {
return "ART debug build";
}
return value;
} catch (IllegalAccessException e) {
return "IllegalAccessException";
} catch (IllegalArgumentException e) {
return "IllegalArgumentException";
} catch (InvocationTargetException e) {
return "InvocationTargetException";
}
} catch (NoSuchMethodException e) {
return "SystemProperties.get(String key, String def) method is not found";
}
} catch (ClassNotFoundException e) {
return "SystemProperties class is not found";
}
}
}
J'espère que cela t'aides.
Pour tous ceux qui ont besoin d'une version JNI:
#include <sys/system_properties.h>
static bool isArtEnabled() {
char buf[PROP_VALUE_MAX] = {};
__system_property_get("persist.sys.dalvik.vm.lib.2", buf);
// This allows libartd.so to be detected as well.
return strncmp("libart", buf, 6) == 0;
}
Ou si vous souhaitez suivre un chemin de code plus proche de ce que le rat de la chaussure a publié,
static bool isArtEnabled(JNIEnv *env)
{
// Per https://developer.Android.com/guide/practices/verifying-apps-art.html
// if the result of System.getProperty("Java.vm.version") starts with 2,
// ART is enabled.
jclass systemClass = env->FindClass("Java/lang/System");
if (systemClass == NULL) {
LOGD("Could not find Java.lang.System.");
return false;
}
jmethodID getProperty = env->GetStaticMethodID(systemClass,
"getProperty", "(Ljava/lang/String;)Ljava/lang/String;");
if (getProperty == NULL) {
LOGD("Could not find Java.lang.System.getProperty(String).");
return false;
}
jstring propertyName = env->NewStringUTF("Java.vm.version");
jstring jversion = (jstring)env->CallStaticObjectMethod(
systemClass, getProperty, propertyName);
if (jversion == NULL) {
LOGD("Java.lang.System.getProperty('Java.vm.version') did not return a value.");
return false;
}
const char *version = env->GetStringUTFChars(jversion, JNI_FALSE);
// Lets flip that check around to better bullet proof us.
// Consider any version which starts with "1." to be Dalvik,
// and all others to be ART.
bool isArtEnabled = !(strlen(version) < 2 ||
strncmp("1.", version, 2) == 0);
LOGD("Is ART enabled? %d (%s)", isArtEnabled, version);
env->ReleaseStringUTFChars(jversion, version);
return isArtEnabled;
}
Les documents Android donnent en fait la suggestion suivante:
Vous pouvez vérifier quel runtime est utilisé en appelant System.getProperty ("Java.vm.version"). Si ART est utilisé, la valeur de la propriété est "2.0.0" ou supérieure.
Cela semble exact sur mon Nexus 4 avec ART activé (exécutant Android 4.4.4). Nexus 5 sur Dalvik a renvoyé 1.6.0
.
Je pense que vous devriez pouvoir utiliser System.getProperty avec Java.vm.name
comme clé. Dans le JavaDoc, sa valeur est Dalvik
, ce qui, espérons-le, est Art
ou ART
lorsque vous utilisez ce runtime . Ça vaut la peine d'essayer...
final String vm = VMRuntime.getRuntime().vmLibrary();
puis comparez vm avec "libdvm.so" ou "libart.so" pour vérifier s'il s'agit de Dalvik ou ART.
Une solution simple:
String vm = System.getProperty("Java.vm.name") + " " + System.getProperty("Java.vm.version");
Sur mon Android 8.0 (API 26) téléphone, il renvoie Dalvik 2.1.0.