類似問題發現了Android運行時(Dalvik的或藝術)在Xamarin這一個:How can I detect the Android runtime (Dalvik or ART)?我怎樣才能
如何做到這一點在Xamarin.Android(MonoDroid的),因爲我沒有Java反射嗎?
由於ART尚未在Xamarin上工作,我想檢測它並向用戶顯示一些友好的消息,而不是應用程序崩潰。謝謝。
類似問題發現了Android運行時(Dalvik的或藝術)在Xamarin這一個:How can I detect the Android runtime (Dalvik or ART)?我怎樣才能
如何做到這一點在Xamarin.Android(MonoDroid的),因爲我沒有Java反射嗎?
由於ART尚未在Xamarin上工作,我想檢測它並向用戶顯示一些友好的消息,而不是應用程序崩潰。謝謝。
似乎在模擬器上工作,不知道實際設備發生了什麼,直到它得到了一些負責人:
[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";
}
}
}
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;
}
}
謝謝。我實現了簡單的版本 - 只是var value = getMethod.Invoke(...)。ToString();而對於ART,它會返回「libart.so」,但對於Dalvik,它實際上會返回「Dalvik」(而不是「libdvm.so」),這很奇怪,但足以檢測ART – rouen