如何检测Android运行时(Dalvik或ART)?

Google在Android 4.4中添加了一个新的ART运行时。 如何确定ART或Dalvik是否是当前运行时?

更新

至less,早在2014年6月,Google就发布了正式文档, 介绍如何正确validation当前使用的运行时间 :

您可以通过调用System.getProperty(“java.vm.version”)来validation正在使用哪个运行时。 如果ART正在使用,则属性值为“2.0.0”或更高。

这样,现在就不需要经过反思,只需要检查相应的系统属性:

private boolean getIsArtInUse() { final String vmVersion = System.getProperty("java.vm.version"); return vmVersion != null && vmVersion.startsWith("2"); } 

一种可能的方法是通过reflection读取相应的SystemProperty

样品:

 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"; } } } 

希望这可以帮助。

对于任何需要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; } 

或者,如果你想跟随一个代码path更接近鞋鼠发布,

 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; } 

Android文档实际上给出了以下build议:

您可以通过调用System.getProperty(“java.vm.version”)来validation正在使用哪个运行时。 如果ART正在使用,则属性值为“2.0.0”或更高。

这似乎准确的启用了我的Nexus 4 W / ART(运行Android 4.4.4)。 Dalvik上的Nexus 5返回1.6.0

我认为你应该能够使用java.vm.name作为关键字的System.getProperty 。 在JavaDoc中,它的值是Dalvik ,让我们希望在使用该运行 Dalvik它是ArtART 。 值得一试…

final String vm = VMRuntime.getRuntime().vmLibrary();

然后比较vm与“libdvm.so”或“libart.so”来检查它是否是Dalvik或ART。

参考: https : //gitorious.org/cyandreamproject/android_frameworks_base/commit/4c3f1e9e30948113b47068152027676172743eb1