如何检测Android运行时(Dalvik或ART)?
谷歌在安卓4.4上增加了一个新的运行时。如何确定当前运行时是ART还是Dalvik?我认为您应该能够使用如何检测Android运行时(Dalvik或ART)?,android,dalvik,android-4.4-kitkat,art-runtime,Android,Dalvik,Android 4.4 Kitkat,Art Runtime,谷歌在安卓4.4上增加了一个新的运行时。如何确定当前运行时是ART还是Dalvik?我认为您应该能够使用java.vm.name作为键。 在JavaDoc中,它的值是Dalvik,我们希望在使用该运行时它是Art或Art。值得一试…更新 至少,早在2014年6月,谷歌就发布了关于以下内容的官方文件: 您可以通过调用System.getProperty(“java.vm.version”)来验证正在使用哪个运行时。如果正在使用艺术,则该属性的值为“2.0.0”或更高 这样,现在就不需要进行反射,只
java.vm.name
作为键。
在JavaDoc中,它的值是Dalvik
,我们希望在使用该运行时它是Art
或Art
。值得一试…更新
至少,早在2014年6月,谷歌就发布了关于以下内容的官方文件:
您可以通过调用System.getProperty(“java.vm.version”)来验证正在使用哪个运行时。如果正在使用艺术,则该属性的值为“2.0.0”或更高
这样,现在就不需要进行反射,只需检查相应的系统属性:
private boolean getIsArtInUse() {
final String vmVersion = System.getProperty("java.vm.version");
return vmVersion != null && vmVersion.startsWith("2");
}
一种可能的方法是通过反射读取相应的数据 样本:
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";
}
}
}
package com.example.getcurrentruntimevalue;
导入android.app.Activity;
导入android.os.Bundle;
导入android.widget.TextView;
导入java.lang.reflect.InvocationTargetException;
导入java.lang.reflect.Method;
公共类MainActivity扩展了活动{
私有静态最终字符串SELECT_RUNTIME_PROPERTY=“persist.sys.dalvik.vm.lib”;
私有静态最终字符串LIB_DALVIK=“libdvm.so”;
私有静态最终字符串LIB_ART=“libart.so”;
私有静态最终字符串LIB_ART_D=“libartd.so”;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv=(TextView)findViewById(R.id.current\u runtime\u值);
setText(getCurrentRuntimeValue());
}
私有CharSequence getCurrentRuntimeValue(){
试一试{
Class systemProperties=Class.forName(“android.os.systemProperties”);
试一试{
方法get=systemProperties.getMethod(“get”,
String.class,String.class);
if(get==null){
返回“WTF?!”;
}
试一试{
最终字符串值=(字符串)get.invoke(
系统属性,选择运行时属性,
/*假设违约为*/“Dalvik”);
if(LIB_DALVIK.equals(value)){
返回“Dalvik”;
}否则,如果(自由艺术等于(价值)){
回归“艺术”;
}否则,如果(自由艺术等于(价值)){
返回“艺术调试构建”;
}
返回值;
}捕获(非法访问例外e){
返回“IllegalAccessException”;
}捕获(IllegalArgumentException e){
返回“IllegalArgumentException”;
}捕获(调用TargetException e){
返回“InvocationTargetException”;
}
}捕获(无此方法例外){
返回“未找到SystemProperties.get(字符串键、字符串定义)方法”;
}
}catch(classnotfounde异常){
返回“未找到SystemProperties类”;
}
}
}
希望这有帮助。最终字符串vm=VMRuntime.getRuntime().vmLibrary()代码> 然后将vm与“libdvm.so”或“libart.so”进行比较,以检查它是Dalvik还是ART 参考资料:专家实际上给出了以下建议: 您可以通过调用System.getProperty(“java.vm.version”)来验证正在使用哪个运行时。如果正在使用艺术,则该属性的值为“2.0.0”或更高
这在我的Nexus4W/ART(运行Android 4.4.4)上似乎是准确的。Dalvik上的Nexus 5为需要JNI版本的任何人返回了
1.6.0
:
#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;
}
#包括
静态bool isArtEnabled(){
char buf[PROP_VALUE_MAX]={};
__系统属性获取(“persist.sys.dalvik.vm.lib.2”,buf);
//这使得libartd.so也能被检测到。
返回strncmp(“libart”,buf,6)==0;
}
或者,如果你想遵循更接近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;
}
static bool已启用(JNIEnv*env)
{
//https://developer.android.com/guide/practices/verifying-apps-art.html
//如果System.getProperty(“java.vm.version”)的结果以2开头,
//艺术已启用。
jclass-systemClass=env->FindClass(“java/lang/System”);
if(systemClass==NULL){
LOGD(“找不到java.lang.System”);
返回false;
}
jmethodID getProperty=env->GetStaticMethodID(systemClass,
“getProperty”,“(Ljava/lang/String;)Ljava/lang/String;”;
if(getProperty==NULL){
LOGD(“找不到java.lang.System.getProperty(字符串)”;
返回false;
}
jstringpropertyname=env->NewStringUTF(“java.vm.version”);
jstringjversion=(jstring)env->CallStaticObjectMethod(
systemClass、getProperty、propertyName);
if(jversion==NULL){
LOGD(“java.lang.System.getProperty('java.vm.version')没有返回值。”);
返回false;
}
const char*version=env->GetStringUTFChars(jversion,JNI_FALSE);
//让我们把这张支票翻过来,让我们更好地防弹。
/考虑任何以“1”开头的版本,作为Dalvik,
//所有其他的都是艺术。
bool isArtEnabled=!(strlen(版本)<2||
strncmp(“1.”,版本,2)==0);
LOGD(“是否已启用ART?%d(%s)”,已启用ISARTED,版本);
环境->发布StringUTFChars(jversion,version);
返回已启动;
}
一个简单的解决方案:
String vm = System.getProperty("java.vm.name") + " " + System.getProperty("java.vm.version");
在我的Android 8.0(API 26)手机上,当运行ART:
System.getProperty(“java.vm.name”)
时,它返回Dalvik 2.1.0.System.getProperty(“java.specification.name”)
返回Dalvik核心库
:(嗯,那是最简单的查询方式。也许他们没有改变它,因为艺术没有发行