我已经开始使用Android StrictMode并发现在开发期间始终运行它并不仅仅是我在git中创建的特殊分支上会很棒。我这样做的原因是我的应用程序要求以1.6及更高版本运行。
我在Android开发者博客上看到你可以设置它,以便通过反射激活它。我只是想知道它实际上是什么样的,如果有可能在这里(或其他地方)记录这些,而不是让每个想要使用它的人自己解决。
答案 0 :(得分:9)
我已阅读过Manfred的博文,但如果您将目标平台版本设置为低于2.3 ,则无效,因为StrictMode.enableDefaults();
方法不可用。
这是我的解决方案,它完全依赖于反射并且不会产生编译错误:
try {
Class<?> strictModeClass = Class.forName("android.os.StrictMode", true, Thread.currentThread()
.getContextClassLoader());
Class<?> threadPolicyClass = Class.forName("android.os.StrictMode$ThreadPolicy", true, Thread
.currentThread().getContextClassLoader());
Class<?> threadPolicyBuilderClass = Class.forName("android.os.StrictMode$ThreadPolicy$Builder", true,
Thread.currentThread().getContextClassLoader());
Method setThreadPolicyMethod = strictModeClass.getMethod("setThreadPolicy", threadPolicyClass);
Method detectAllMethod = threadPolicyBuilderClass.getMethod("detectAll");
Method penaltyMethod = threadPolicyBuilderClass.getMethod("penaltyLog");
Method buildMethod = threadPolicyBuilderClass.getMethod("build");
Constructor<?> threadPolicyBuilderConstructor = threadPolicyBuilderClass.getConstructor();
Object threadPolicyBuilderObject = threadPolicyBuilderConstructor.newInstance();
Object obj = detectAllMethod.invoke(threadPolicyBuilderObject);
obj = penaltyMethod.invoke(obj);
Object threadPolicyObject = buildMethod.invoke(obj);
setThreadPolicyMethod.invoke(strictModeClass, threadPolicyObject);
} catch (Exception ex) {
Log.w(TAG, ex);
}
答案 1 :(得分:8)
所以我不想等待并决定付出努力并自己实施。它基本上归结为将StrictMode包装在包装器类中,并在运行时通过反射决定是否可以激活它。
我已将其详细记录在in a blog post中,并在github中提供。
答案 2 :(得分:7)
我看到了你的博文。由于您每个Java文件最多只需要设置一次StrictMode,因此简化代码以调用设置是否有意义如下?
这是另一个StrictModeWrapper:
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.os.StrictMode;
public class StrictModeWrapper {
public static void init(Context context) {
// check if android:debuggable is set to true
int applicationFlags = context.getApplicationInfo().flags;
if ((applicationFlags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
.penaltyLog()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.penaltyLog()
.penaltyDeath()
.build());
}
}
}
从您的代码中,您只需执行以下操作:
try {
StrictModeWrapper.init(this);
}
catch(Throwable throwable) {
Log.v("StrictMode", "... is not available. Punting...");
}
其中此是本地上下文,例如您的活动或应用程序或其他内容。这似乎适用于2.3之前的Android,并且还使您能够使用Builder类的其他方法完全按照您的意愿配置StrictMode。
答案 3 :(得分:1)
我已经将上述主题的另一个变体放在一起,我在博文here中概述了这些变体。我的方法的主要区别在于它还为磁盘和vm策略对象提供了包装器,因此您可以轻松地将StrictMode-offending代码包含在临时策略更改中。欢迎提供反馈。
答案 4 :(得分:1)
To Pixel代码我也添加了这个(基于StrictMode Android API示例):
// VM policy
Class<?> VmPolicyClass = Class.forName("android.os.StrictMode$VmPolicy", true, Thread.currentThread().getContextClassLoader());
Class<?> VmPolicyBuilderClass = Class.forName("android.os.StrictMode$VmPolicy$Builder", true, Thread.currentThread().getContextClassLoader());
Method setVmPolicyMethod = strictModeClass.getMethod("setVmPolicy", VmPolicyClass);
Method detectLeakedSqlLiteObjectsMethod = VmPolicyBuilderClass.getMethod("detectLeakedSqlLiteObjects");
Method detectLeakedClosableObjectsMethod = null;
try
{
detectLeakedClosableObjectsMethod = VmPolicyBuilderClass.getMethod("detectLeakedClosableObjects");
}
catch (Exception e) {}
Method penaltyLogMethod = VmPolicyBuilderClass.getMethod("penaltyLog");
Method penaltyDeathMethod = VmPolicyBuilderClass.getMethod("penaltyDeath");
Method VmbuildMethod = VmPolicyBuilderClass.getMethod("build");
Constructor<?> VmPolicyBuilderConstructor = VmPolicyBuilderClass.getConstructor();
Object VmPolicyBuilderObject = VmPolicyBuilderConstructor.newInstance();
Object Vmobj = detectLeakedSqlLiteObjectsMethod.invoke(VmPolicyBuilderObject);
if (detectLeakedClosableObjectsMethod != null) Vmobj = detectLeakedClosableObjectsMethod.invoke(Vmobj);
Vmobj = penaltyLogMethod.invoke(Vmobj);
Vmobj = penaltyDeathMethod.invoke(Vmobj);
Object VmPolicyObject = VmbuildMethod.invoke(Vmobj);
setVmPolicyMethod.invoke(strictModeClass, VmPolicyObject);
答案 5 :(得分:0)
将Android Manifest设置为类似的内容。
< uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16" android:maxSdkVersion="16"/ >
在onCreate Method中使用以下代码。
int SDK_INT = android.os.Build.VERSION.SDK_INT;
} if (SDK_INT>8){
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
注意:禁用警告,因为您已经在检查哪个版本的Android将使用此代码。
如果Android版本高于Android 2.2,则会激活此代码