2011-01-06 34 views
12

Tôi đã bắt đầu sử dụng Android StrictMode và thấy rằng sẽ rất tuyệt khi có nó luôn chạy trong quá trình phát triển chứ không chỉ trên nhánh đặc biệt mà tôi tạo ra trong git. Lý do tôi làm điều này là yêu cầu ứng dụng của tôi chạy với 1.6 trở lên.StrictMode cho các phiên bản nền tảng thấp hơn

Tôi đọc trên blog nhà phát triển Android mà bạn có thể thiết lập để bạn kích hoạt nó thông qua phản ánh. Tôi chỉ tự hỏi làm thế nào mà thực sự sẽ như thế và nếu nó có thể có thể có tài liệu này ở đây (hoặc ở một nơi khác) hơn là có tất cả mọi người muốn sử dụng nó làm việc ra chính mình.

+0

nếu tôi không nhận được câu trả lời ở đây tôi sẽ tự mình tìm ra khi tôi có một chút thời gian để làm điều đó .. cần phải chuẩn bị cho andevcon tại thời điểm này .. –

Trả lời

8

Vì vậy, tôi không muốn chờ đợi và quyết định nỗ lực và tự thực hiện điều này. Về cơ bản nó tóm tắt để gói StrictMode trong một lớp trình bao bọc và quyết định thời gian chạy qua sự phản chiếu nếu chúng ta có thể kích hoạt nó.

Tôi đã ghi lại chi tiết in a blog post và cung cấp trong github.

+0

@bla ... vui lòng xóa sổ xuống của bạn .. Tôi đã sửa liên kết .. đây là 5 tuổi. Mọi thứ di chuyển xung quanh .. –

+0

Cảm ơn Manfred; một downvote nói chung là một cách hiệu quả để có được các liên kết cố định;). Bạn nên kiểm tra các lớp MorseFlashApplication và StrictModeWrapper. – bla

7

Tôi đã xem bài đăng trên blog của bạn. Vì bạn chỉ muốn thiết lập StrictMode nhiều nhất một lần cho mỗi tệp Java, liệu nó có tạo ra bất kỳ ý nghĩa nào để đơn giản hóa mã để gọi cho thiết lập như sau không?

Dưới đây là một StrictModeWrapper thay thế:

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

Từ mã của bạn, bạn chỉ cần làm như sau:

try { 
    StrictModeWrapper.init(this); 
} 
catch(Throwable throwable) { 
    Log.v("StrictMode", "... is not available. Punting..."); 
} 

nơi đây là bối cảnh địa phương, chẳng hạn như Hoạt động hoặc ứng dụng của bạn hay bất cứ cái gì. Điều này dường như làm việc cho Android trước 2.3, và cũng cung cấp cho bạn sức mạnh của việc sử dụng các phương thức khác của các lớp Builder để cấu hình chính xác StrictMode như bạn muốn.

+0

Có .. điều đó sẽ làm việc quá và có thể là một chút ngắn hơn trong ý nghĩa rằng nó thậm chí không cố gắng sử dụng sự phản chiếu nhưng chỉ làm đầy đủ trên init. Nó là một chút ít linh hoạt theo cách này mặc dù. Tuy nhiên, bạn chỉ muốn làm điều này một lần. Tôi chỉ làm điều đó trong onCreate của lớp ứng dụng, đó là một singleton đã anyway .. –

+0

Tôi đã từng thấy một câu trả lời từ Dianne Hackborn trên nhóm nhà phát triển Android đề nghị chống lại mở rộng ứng dụng nếu nó không hoàn toàn cần thiết. Các chính sách áp dụng cho các chủ đề, vì vậy bạn có thể khởi tạo StrictMode trong onCreate() của hoạt động launcher của bạn, và sau đó nó sẽ tốt như khởi tạo từ ứng dụng vì nó sẽ áp dụng cho chủ đề chính. Trừ khi tất nhiên bạn kích hoạt các chủ đề bổ sung mà bạn muốn theo dõi, nhưng bạn cần thiết lập StrictMode trên các chủ đề đó ngay cả khi bạn đã khởi tạo từ Ứng dụng. –

+0

Có. Đó là một khả năng khác. Tôi cũng thấy rằng đề nghị từ Dianne, nhưng nhiều ứng dụng tôi thấy mở rộng ứng dụng và nó hoạt động khá tốt theo cách đó. Giống như họ nói .. có rất nhiều cách để da một con mèo ;-) –

1

Tôi đã kết hợp một biến thể khác về chủ đề ở trên, mà tôi đã phác thảo trong bài đăng trên blog here. Sự khác biệt chính trong cách tiếp cận của tôi là nó cũng cung cấp các trình bao bọc cho các đối tượng chính sách đĩa và vm, để bạn dễ dàng có thể gắn mã mã StrictMode-offending với các thay đổi chính sách tạm thời. Phản hồi được hoan nghênh.

9

Tôi đã đọc bài đăng trên blog của Manfred nhưng nó không hoạt động nếu bạn đặt phiên bản nền tảng đích thấp hơn 2.3 vì phương pháp StrictMode.enableDefaults(); không khả dụng.

Đây là giải pháp của tôi dựa hoàn toàn vào suy nghĩ và không tạo ra lỗi biên dịch:

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

Việc thực hiện là trong github và đã được thử nghiệm và sử dụng bởi nhiều người. Nó hoạt động tốt. Tôi dùng nó mỗi ngày. Nhưng có ... nếu bạn cần mục tiêu dưới 2,3, thủ thuật của bạn sẽ hoạt động tốt. –

+0

@ManfredMoser Lý do duy nhất tôi đăng nó là cần hỗ trợ các mục tiêu thấp hơn 2.3. Giải pháp của bạn là tốt, nhưng trong trường hợp đặc biệt này, nó không hoạt động. – pixel

+0

nhờ @ManfredMoser –

1

mã Pixel Tôi cũng đã thêm này (dựa trên StrictMode Android dụ 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

Đặt Tệp kê khai Android thành nội dung như thế này.

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

sử dụng mã bên dưới trong phương pháp 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); 

} 

Lưu ý: Tắt cảnh báo khi bạn đang kiểm tra phiên bản Android sẽ sử dụng mã này.

Mã này sẽ được kích hoạt nếu phiên bản Android cao hơn Android 2.2

+0

Điều này sẽ không hoạt động trên các phiên bản Android cũ hơn vì nó giả định lớp StrictMode khả dụng .. không phải như vậy. –

+0

Tôi đang sử dụng ứng dụng này trên Android 2.2 với ứng dụng mới Popup Facebook, Đối với điều này, bạn phải chọn mục tiêu như đã nêu ở trên bài đăng sẽ có lỗi trong logcat nếu phiên bản android thấp hơn 2.3 nhưng có một mã chết. – PravinDodia

+0

Khi nói về các phiên bản cũ, các giải pháp khác hoạt động trở lại 1.1 ... –

Các vấn đề liên quan