How can I detect the Android runtime (Dalvik or ART)?

前端 未结 6 1105
长情又很酷
长情又很酷 2021-01-30 13:22

Google added a new ART runtime with Android 4.4. How can I determine whether ART or Dalvik is the current runtime?

6条回答
  •  鱼传尺愫
    2021-01-30 13:59

    Update

    At least, as early as June 2014 Google has released an official documentation on how to correctly verify the current runtime in use:

    You can verify which runtime is in use by calling System.getProperty("java.vm.version"). If ART is in use, the property's value is "2.0.0" or higher.

    With that, now there is no need to go through reflection and simply check the corresponding system property:

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

    One possible way is to read the respective SystemProperty through reflection.

    Sample:

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

    Hope this helps.

提交回复
热议问题