2011-01-06 73 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

相關問題