2011-01-06 46 views
12

我已经开始使用Android StrictMode,并且发现在开发过程中始终运行它并非只是在我在git中创建的特殊分支上会很高兴。我这样做的原因是我的应用程序要求使用1.6或更高版本运行。适用于较低平台版本的StrictMode

我在android开发人员博客上看到,您可以对其进行设置,以便通过反射来激活它。我只是想知道这实际上是怎么样的,如果有可能在这里(或其他地方)记录这些信息,而不是让每个人都想使用它,他们自己就能解决问题。

+0

如果我没有在这里得到答案,我会在我有一点时间做这件事情的时候想出它自己..需要为andevcon做准备,虽然.. – 2011-01-06 02:21:29

回答

8

因此,我不想等待,并决定自己努力并实现。它基本上归结为将StrictMode包装在包装类中,并在运行时通过反射来决定是否可以激活它。

我已将其详细记录在in a blog post中,并使其在github中可用。

+0

@bla ...好心地删除你的downvote ..我固定链接..这是5岁。东西移动.. – 2016-03-29 22:38:55

+0

谢谢曼弗雷德; downvote通常是固定链接的有效方式;)。应该检查MorseFlashApplication和StrictModeWrapper类。 – bla 2016-03-29 22:54:43

7

我看到了您的博客文章。既然你只想每个Java文件最多设置一次StrictMode,那么简化代码来调用setup如下所示是有意义的吗?

这里有一个备用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。

+0

是的,这也可以起作用,可能会缩短一点,因为它甚至不尝试使用反射,但只是在初始化时完成。但这种方式稍微有点不灵活。不过,你只想这样做一次。我只是在应用程序类的onCreate中完成它,这已经是单身。 – 2011-01-18 05:11:54

+0

我曾经看到Dianne Hackborn在Android开发人员小组上的一个答案,如果它不是绝对必要的,那么建议您不要扩展应用程序。这些策略适用于线程,因此您可以在启动器活动的onCreate()中初始化StrictMode,然后它应该像从Application初始化一样好,因为它适用于主线程。除非你启动了你想要监视的其他线程,但是即使你是从Application初始化的,你也需要在这些线程上设置StrictMode。 – 2011-01-18 14:25:10

+0

是的。那是另一种可能性。我也看到了Dianne的建议,但是我看到的很多应用程序扩展了应用程序,并且它的工作方式非常好。就像他们说的那样......有许多方法可以为一只猫蒙皮;-) – 2011-01-18 23:49:44

1

我把以上主题的另一个变体放在一起,我在博客文章here中列出了这个变体。我的方法的主要区别在于它还提供了磁盘和虚拟机策略对象的包装器,因此您可以轻松地将临时策略更改包含在严格模式代码中。欢迎反馈。

9

我读过曼弗雷德的博客文章,但它不工作,如果你设置目标平台版本低于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); 
    } 
+0

该实现在github中,并且已经被许多人测试和使用。它工作得很好。我每天都使用它。但是,是的......如果你需要低于2.3的目标,你的诡计也会起作用。 – 2011-11-15 17:47:39

+0

@ManfredMoser我发布它的唯一原因是需要支持低于2.3的目标。你的解决方案很好,但在这种特殊情况下它不起作用。 – pixel 2011-11-15 20:06:24

+0

感谢@ManfredMoser – 2012-03-02 15:09:55

1

像素代码我还添加了这个(基于Android的StrictMode 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); 
0

将Android Manifest设置为这样。

< uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16" android:maxSdkVersion="16"/ > 

在onCreate方法中使用下面的代码。

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

+0

因为它假定类StrictMode可用..这不适用于较旧的Android版本。事实并非如此。 – 2012-09-04 15:55:50

+0

我在我的Android 2.2上使用了这个新的应用程序Popup Facebook,为此,您必须选择target,如上所述,在postcat中会出现错误,如果android版本低于2.3,但这将是关于声明有一个死码。 – PravinDodia 2012-09-09 19:03:42

+0

当谈到旧版本时,其他解决方案的工作原理是1.1 ... – 2012-09-10 02:42:37

相关问题