【问题标题】:How can I detect the Android runtime (Dalvik or ART) in Xamarin如何在 Xamarin 中检测 Android 运行时(Dalvik 或 ART)
【发布时间】:2014-02-25 14:55:03
【问题描述】:

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

如何在 Xamarin.Android (MonoDroid) 中完成,因为我这里没有 java 反射?

由于 ART 尚未在 xamarin 上运行,我想检测它并至少在应用程序崩溃时向用户显示一些友好的消息。谢谢。

【问题讨论】:

    标签: android xamarin.android xamarin


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢。我实现了简单的版本 - 只是 var value = getMethod.Invoke(...).ToString();对于 ART,它返回“libart.so”,但对于 Dalvik,它实际上返回“Dalvik”(不是“libdvm.so”),这很奇怪,但足以检测 ART
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2013-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-30
      相关资源
      最近更新 更多