Vraag Aangepaste logboeken voor Android-applicaties


Ik wil een aangepaste logger maken voor een Android-applicatie. Het loggen moet in een aparte thread worden gedaan, omdat de applicatie veel informatie genereert. Ik wil de Android-logs niet gebruiken omdat ik de logs in een specifieke indeling moet schrijven. Meerdere threads schrijven tegelijkertijd naar het logbestand, dus ik heb een wachtrij gebruikt om de logberichten te bewaren

Hier is de code die ik heb

Queue<LogEntry> logQueue = new LinkedBlockingQueue<LogEntry>();
LogWritterThread logWritterThread = new LogWritterThread();

// to queue the log messages
public void QueueLogEntry(String message)
{
    LogEntry le = new LogEntry(message);
    {
        logQueue.add(le);
        logQueue.notifyAll();
    }

logWritterThread.start();
}

    class LogWritterThread extends Thread 
{
    public void run() 
    {
        try 
        {
            while(true)
            {
                //thread waits until there are any logs to write in the queue
                if(logQueue.peek() == null)
                    synchronized(logQueue){
                        logQueue.wait();
                    }
                if(logQueue.peek() != null)
                {
                    LogEntry logEntry;
                    synchronized(logQueue){
                        logEntry = logQueue.poll();
                    }

                    // write the message to file
                }
                if(Thread.interrupted())
                    break;
            }
        } 
        catch (InterruptedException e) 
        {                
        }
    }
}

Is er iets mis met deze code? of een betere manier om een ​​logboekwachtrij te maken

Bedankt, Anuj


12
2018-02-25 12:24


oorsprong


antwoorden:


Voor Java BlockingQueue-implementaties zijn al synchronisatieproblemen ingebouwd. Uw gebruik van wait, notify en synchronized is overbodig en niet nodig.

Probeer het Producer / Consumer-voorbeeld na te bootsen in de BlockingQueue javadoc 

class LogEntry {
  private final String message;

  LogEntry(String msg) {
    message = msg;
  }
}

class LogProducer {
   private final BlockingQueue<LogEntry> queue;

   LogProducer(BlockingQueue<LogEntry> q) {
     queue = q;
   }

   public void log(String msg) {
      queue.put(new LogEntry(msg));
   }
 }

class LogConsumer implements Runnable {
   private final BlockingQueue<LogEntry> queue;

   LogConsumer(BlockingQueue<LogEntry> q) {
     queue = q;
   }

   public void run() {
     try {
       while(true) {
         LogEntry entry = queue.take();
         // do something with entry
       }
     } catch(InterruptedException ex) {
       // handle
     }
   }
}

class Setup {
  public static void main(String[] args) {
    BlockingQueue<LogEntry> queue = new LinkedBlockingQueue<LogEntry>();
    LogConsumer c = new LogConsumer(queue);
    new Thread(c).start();

    LogProducer p = new LogProducer(queue);
    p.log("asynch");
    p.log("logging");
  }
}

5
2018-02-25 20:31



Ik zou een handler gebruiken - ik hou van handlers omdat ze een wachtrij en een berichtenreeks implementeren die allemaal thread safe is. Dat betekent dat je een klasse kunt maken die een handler uitbreidt en die klasse overal in je project gebruikt. Met een paar regels code met een handler kunt u uw bestaande code drastisch inkrimpen.

Google's documentatie: http://developer.android.com/reference/android/os/Handler.html

Dit is een heel eenvoudig voorbeeld: http://saigeethamn.blogspot.com/2010/04/threads-and-handlers-android-developer.html

dit is een beter voorbeeld omdat ze "msg.what" gebruiken om te beslissen wat ze moeten doen (wat je nodig hebt voor verschillende niveaus van loggen): https://idlesun.wordpress.com/2010/12/12/android-handler-and-message-tutorial/


2
2018-02-25 20:13