2010-12-30 35 views
20

Tôi muốn sử dụng java.util.logging trên Android. Tôi muốn cấu hình hệ thống đăng nhập với logging.properties. Nhưng làm cách nào tôi có thể cho Android biết bằng cách sử dụng tệp cấu hình cụ thể? Ví dụ, tôi đã đặt logging.properties trong root classpath của ứng dụng. Cách Android biết vị trí của logging.properties.Cách định cấu hình java.util.logging trên Android?

Cảm ơn

Trả lời

4

Thông thường, người dùng sử dụng android.util.Log để đăng nhập Android. Có một số ưu điểm chính khi sử dụng trình ghi nhật ký đó, chẳng hạn như có thể sử dụng adb logcat để xem kết quả ghi nhật ký được gửi tới các nhật ký đó.

Bạn có thể thử đặt logging.properties trong assets/ hoặc res/raw/. Nếu Android không chọn những người ở đó, thì người ta có thể sử dụng java.util.logging.LogManager. readConfiguration(java.io.InputStream) để buộc tải. (Bạn có thể sử dụng các lớp Tài nguyên và AssetManager để lấy tệp dưới dạng InputStream).

+0

Cảm ơn bạn rất nhiều. Cách tiếp cận này hoạt động tốt. Bây giờ tôi phải đấu tranh để viết nhật ký cho sdcard. – tangjie

+0

@tangjie không chắc chắn mục tiêu cuối cùng của bạn là gì, nhưng tôi sẽ xem xét việc lưu trữ các bản ghi trong ứng dụng của bạn và sau đó gửi chúng tới máy chủ nơi bạn thực sự có quyền truy cập vào – philipp

47

Đây hiện là câu hỏi thường gặp cho một trong các dự án của tôi, hy vọng nhiều người sẽ tìm thấy điều này ở đây: java.util.logging hoạt động tốt trên Android. Xin vui lòng không sử dụng bất cứ điều gì khác trong mã của bạn, đăng nhập khuôn khổ giống như một dịch hại trong thế giới Java.

Điều bị hỏng là trình xử lý ghi nhật ký mặc định được gửi đi với Android, nó bỏ qua bất kỳ thông điệp tường trình nào có mức độ mịn hơn INFO. Bạn không thấy thông báo DEBUG v.v.

Lý do là cuộc gọi đến Log.isLoggable() trong AndroidHandler.java:

https://github.com/android/platform_frameworks_base/blob/master/core/java/com/android/internal/logging/AndroidHandler.java

Đây là cách bạn sửa chữa nó:

import android.util.Log; 
import java.util.logging.*; 

/** 
* Make JUL work on Android. 
*/ 
public class AndroidLoggingHandler extends Handler { 

    public static void reset(Handler rootHandler) { 
     Logger rootLogger = LogManager.getLogManager().getLogger(""); 
     Handler[] handlers = rootLogger.getHandlers(); 
     for (Handler handler : handlers) { 
      rootLogger.removeHandler(handler); 
     } 
     rootLogger.addHandler(rootHandler); 
    } 

    @Override 
    public void close() { 
    } 

    @Override 
    public void flush() { 
    } 

    @Override 
    public void publish(LogRecord record) { 
     if (!super.isLoggable(record)) 
      return; 

     String name = record.getLoggerName(); 
     int maxLength = 30; 
     String tag = name.length() > maxLength ? name.substring(name.length() - maxLength) : name; 

     try { 
      int level = getAndroidLevel(record.getLevel()); 
      Log.println(level, tag, record.getMessage()); 
      if (record.getThrown() != null) { 
       Log.println(level, tag, Log.getStackTraceString(record.getThrown())); 
      } 
     } catch (RuntimeException e) { 
      Log.e("AndroidLoggingHandler", "Error logging message.", e); 
     } 
    } 

    static int getAndroidLevel(Level level) { 
     int value = level.intValue(); 
     if (value >= 1000) { 
      return Log.ERROR; 
     } else if (value >= 900) { 
      return Log.WARN; 
     } else if (value >= 800) { 
      return Log.INFO; 
     } else { 
      return Log.DEBUG; 
     } 
    } 
} 

Trong hoạt động/code khởi tạo chính về ứng dụng của bạn:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    AndroidLoggingHandler.reset(new AndroidLoggingHandler()); 
    java.util.logging.Logger.getLogger("my.category").setLevel(Level.FINEST); 
... 

TL; DR: Có, bạn có thể sử dụng một số thuộc tính ma thuật, hoặc lệnh adb shell hoặc thậm chí tìm hiểu cách trình xử lý ghi nhật ký nguệch ngoạc của DalvikLogging.loggerNameToTag chuyển đổi tên danh mục thành thẻ (mà bạn phải làm cho các thuộc tính và vỏ ma thuật đó) lệnh), nhưng tại sao lại bận tâm? Không đăng nhập đủ đau đớn sao?

+1

Bằng vòng đời Android, nơi tốt nhất để gọi trình xử lý này là onCreate() từ một lớp con của ứng dụng và khai báo lớp này trên tệp kê khai. Vì nếu vì một lý do nào đó hoạt động chính không xuất hiện (từ một phần, dịch vụ, v.v.) mã vẫn chạy. – Renascienza

1

Ít nhất trên Android 4.3, với thay đổi Handler, nếu bạn sử dụng

adb shell setprop log.tag.YOURTAG DEBUG 

Bạn có thể xem các tin nhắn đăng nhập lên đến Level.FINE trong logcat. Tôi đã không tìm ra cách để đăng nhập cấp độ cao hơn, nhưng đó là đủ cho tôi.

1

Trong trường hợp một trong các bạn chỉ muốn định tuyến đầu ra java.util.logging từ thư viện của bên thứ ba, điều này có thể đạt được khá dễ dàng với SLF4J và jul-to-slf4j bridge của nó. Điều này cũng phù hợp với các tuyên bố đăng nhập FINEFINEST nhật ký, BTW.

Đây là sự phụ thuộc maven

<dependency> 
    <groupId>org.slf4j</groupId> 
    <artifactId>jul-to-slf4j</artifactId> 
    <version>${slf4j.version}</version> 
</dependency> 

Để bootstrap nó, đặt sau đây trong lớp Application của bạn, Roboguice Mô-đun hoặc ở một nơi khác, nơi nó được thực hiện trước khi tuyên bố đăng nhập đầu tiên của bạn. (Việc cấu hình điều này trong assets/logging.properties dường như không hoạt động, thật không may).

/* 
* add SLF4JBridgeHandler to j.u.l's root logger, should be done once 
* during the initialization phase of your application 
*/ 
SLF4JBridgeHandler.install(); 

Bạn có thể sau đó, hoặc

  • cấu hình tất cả các báo cáo đăng nhập của bạn từ assets/logback.xml (sử dụng logback-android). Xem here để lập bản đồ cấp độ nhật ký.

  • hoặc chỉ sử dụng SLF4J-android để chuyển tiếp các báo cáo nhật ký tới logcat. Để làm như vậy, chỉ cần đặt phụ thuộc sau đây để classpath của bạn, không có cấu hình hơn nữa yêu cầu:

    <dependency> 
        <groupId>org.slf4j</groupId> 
        <artifactId>slf4j-android</artifactId> 
        <version>${slf4j.version}</version> 
    </dependency> 
    

tôi thực hiện điều này sử dụng thành công

<properties> 
    <slf4j.version>1.7.6</slf4j.version> 
</properties> 

Note:

  • Vui lòng đọc phần của tài liệu jul-to-slf4j liên quan đến hiệu suất cẩn thận!
  • Nếu bạn sử dụng LogcatAppender hãy nhớ rằng các thông điệp nhật ký JUL (ngoại trừ các thông điệp có mức độ mịn hơn INFO) được chuyển đến logcat bằng Android. Vì vậy, hãy đảm bảo áp dụng các bộ lọc thích hợp để tránh trùng lặp.
+0

Nó hoạt động nhưng đối với tôi thông điệp tường trình với mức độ tốt hơn so với INFO không được hiển thị với adb logcat (slf4j 1.7.21). – user905686

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