¿Cómo puedo detectar el tiempo de ejecución de Android (Dalvik o ART)?
Google agregó un nuevo ART tiempo de ejecución con Android 4.4. ¿Cómo puedo determinar si ART o Dalvik es el tiempo de ejecución actual?
5 answers
Actualizar
Al menos, ya en junio de 2014 Google ha publicado una documentación oficial sobre cómo verificar correctamente el tiempo de ejecución actual en uso :
Puede verificar qué tiempo de ejecución está en uso llamando al Sistema.getProperty ("java.vm.versión"). Si el ARTE está en uso, el valor de la propiedad es "2.0.0" o superior.
Con eso, ahora no hay necesidad de ir a través de la reflexión y simplemente comprobar la propiedad del sistema correspondiente:
private boolean getIsArtInUse() {
final String vmVersion = System.getProperty("java.vm.version");
return vmVersion != null && vmVersion.startsWith("2");
}
Uno forma posible es leer el respectivo SystemProperty
a través de la reflexión.
Muestra:
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";
}
}
}
Espero que esto ayude.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-24 21:42:57
Para cualquiera que necesite una versión 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;
}
O si quieres seguir una ruta de código más cercana a lo que publicó shoe rat,
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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-27 00:17:29
Los Android docs en realidad dan la siguiente sugerencia:
Puede verificar qué tiempo de ejecución está en uso llamando al Sistema.getProperty ("java.vm.versión"). Si el ARTE está en uso, el valor de la propiedad es "2.0.0" o superior.
Esto parece exacto en mi Nexus 4 w/ ARTE habilitado (ejecutando Android 4.4.4). Nexus 5 en Dalvik devolvió 1.6.0
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-02 00:22:28
Creo que debería ser capaz de utilizar el sistema .getProperty con java.vm.name
como clave.
En el JavaDoc su valor es Dalvik
, que esperemos que sea Art
o ART
cuando se usa ese tiempo de ejecución . Vale la pena intentarlo...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-07 08:29:18
final String vm = VMRuntime.getRuntime().vmLibrary();
Y luego comparar vm con "libdvm.so" o "libart.so" para comprobar si es Dalvik o ART.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-18 15:39:17