如何在Xamarin中检测Android运行时(Dalvik或ART)

时间:2014-02-25 14:55:04

标签: android xamarin.android xamarin

与此类似的问题:How can I detect the Android runtime (Dalvik or ART)?

如何在Xamarin.Android(MonoDroid)中执行此操作,因为我在这里没有java反射?

由于ART尚未开发xamarin,我想检测它并向用户显示一些友好的消息,而不是至少应用程序崩溃。感谢。

2 个答案:

答案 0 :(得分:3)

似乎可以在模拟器上工作,不知道实际设备会发生什么变化,直到它收取一些费用:

[Activity (Label = "RuntimeActivity", MainLauncher = true)]
public class RuntimeActivity : Activity 
{
    private static readonly string SELECT_RUNTIME_PROPERTY = "persist.sys.dalvik.vm.lib";
    private static readonly string LIB_DALVIK = "libdvm.so";
    private static readonly string  LIB_ART = "libart.so";
    private static readonly string  LIB_ART_D = "libartd.so";

    override protected void OnCreate(Bundle savedInstanceState) {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.runtime);

        var tv = FindViewById<TextView>(Resource.Id.textView1);
        tv.Text = getCurrentRuntimeValue ();
    }

    private string getCurrentRuntimeValue() 
    {
        try 
        {
            var systemProperties = Java.Lang.Class.ForName("android.os.SystemProperties");

            try 
            {
                var str = new Java.Lang.String();
                var getMethod = systemProperties.GetMethod("get", str.Class, str.Class);

                if (getMethod == null) 
                {
                    return "WTF?!";
                }

                try 
                {
                    var value = getMethod.Invoke(systemProperties, SELECT_RUNTIME_PROPERTY,
                        /* Assuming default is */"Dalvik").ToString();
                    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) 
                {
                    Log.Error(this.ToString(), e.Message);
                    return "IllegalAccessException";
                } 
                catch (IllegalArgumentException e) 
                {
                    Log.Error(this.ToString(), e.Message);
                    return "IllegalArgumentException";
                } 
                catch (InvocationTargetException e) 
                {
                    Log.Error(this.ToString(), e.Message);
                    return "InvocationTargetException";
                }
            } 
            catch (NoSuchMethodException e) 
            {
                Log.Error(this.ToString(), e.Message);
                return "SystemProperties.get(String key, String def) method is not found";
            }
        } 
        catch (ClassNotFoundException e) 
        {
            Log.Error(this.ToString(), e.Message);
            return "SystemProperties class is not found";
        }
    }
}

答案 1 :(得分:1)

Xamarin.Android本身使用__system_property_get,这是一个稳定的,有文档记录的API,因此you can use P/Invoke to do the same

// <sys/system_properties.h>
[DllImport ("/system/lib/libc.so")]
static extern int __system_property_get (string name, StringBuilder value);

const int MaxPropertyNameLength   = 32; // <sys/system_properties.h>
const int MaxPropertyValueLength  = 92; // <sys/system_properties.h>

static bool OnArt {
    get {
        var buf = new StringBuilder (MaxPropertyValueLength + 1);
        int n   = __system_property_get ("persist.sys.dalvik.vm.lib", buf);
        if (n > 0)
            return buf.ToString () == "libart.so";
        return false;
    }
}