0 Replies - 4441 Views - Last Post: 21 February 2016 - 05:05 AM

#1 NormR   User is online

  • D.I.C Lover
  • member icon

Reputation: 750
  • View blog
  • Posts: 5,632
  • Joined: 25-December 13

[Android] app debugging aids

Posted 21 February 2016 - 05:05 AM

I use these two snippets as an aid for debugging Android apps when my device is not connected to a PC where I could see the logcat.
One writes what is printed with System.out.print statements to a file, the other writes the stack trace to a file for some exceptions.

For catching System.out.print statements:
Define these in the class:
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HHmmss", Locale.US); // Builds Filename
    String rootDir = Environment.getExternalStorageDirectory().getPath();
    final String LogFilePathPfx = rootDir + "/ScreenOnOff_log_";
    final String LogFilePathSfx = "_E.txt";
    private boolean debugging = false;   // controls debug output - set from Settings


This goes in the onCreate() method:
        java.util.Date dt =  new java.util.Date();

        if(debugging) {
	      	 // Quick and dirty debugging
	        String fn = LogFilePathPfx + sdf.format(dt) + LogFilePathSfx;   // 2014-02-02T193504_version 
	
	        try {
				SaveStdOutput.start(fn);  // Start trap for println()s
	   	    } catch (IOException e) {
	   			e.printStackTrace();
	   	    }


This for the onDestroy()
		SaveStdOutput.stop();	// Stop writing to the debug log



The body of the class:
package com.normstools;
//See main() below for sample usage

import java.io.*;

//------------------------------------------------------------------------
public class SaveStdOutput extends PrintStream {
final static boolean    debug = true; //false;      // controls debug output

static OutputStream logfile;
static PrintStream oldStdout = null;
static PrintStream oldStderr = null;

private boolean    echoOutput = true;     //Also output to old setting

//-------------------------------------------------------------------
// Constructor - we're the only one that can use it!
private SaveStdOutput(PrintStream ps, boolean echoOutput) {
	   super(ps);
 this.echoOutput = echoOutput;   
//  System.out.println("SaveStdOutput constructor called");
} // end Constructor

//------------------------------------------------------------
// Starts copying stdout and stderr to the file f.
public static void start(String f) throws IOException {
	   if (oldStdout != null) {
	       if (debug)
	           System.err.println("SaveStdOutput start() called twice");
	       return;                    // Exit if already open
	   }
	  // Create/Open logfile.
	  OutputStream os = new PrintStream(
	               new BufferedOutputStream(
	                   new FileOutputStream(f, true)), true);  // append to current & autoflush
      doCommon(os, true);        
} // end start()

// Copy STDOUT and STDERR to an output stream
public static void start(OutputStream os) {
   doCommon(os, true);
} // end start()
public static void start(OutputStream os, boolean eO) {
   doCommon(os, eO);
} // end start()

//-------------------------------------------------------
// Finish up
private static void doCommon(OutputStream os, boolean echoOutput) {
   // Only allow to be called once
   if (oldStdout != null) {
       if (debug)
           System.err.println("SaveStdOutput start() called twice");
       return;                    // Exit if already open
   }
 logfile = os;
	// Save old settings.
	oldStdout = System.out;
	oldStderr = System.err;

	// Start redirecting the output.
	System.setOut(new SaveStdOutput(System.out, echoOutput));
	System.setErr(new SaveStdOutput(System.err, echoOutput));
} // end doCommon()

//--------------------------------------
// Restores the original settings.
public static void stop() {
   if (oldStdout == null) {
       if (debug)
           System.err.println("SaveStdOutput stop() called before start()");
       return;
   }
	  System.setOut(oldStdout);
      oldStdout = null;              //Clear
	  System.setErr(oldStderr);
   try {
	       logfile.close();
   } catch (Exception ex) {
       System.err.println("SaveStdOutput stop() ex " + ex.getMessage());
       ex.printStackTrace();
   }
} // end stop()

//   Override the PrintStream write methods
public void write(int B)/>/> {
   try {
	   logfile.write(B)/>/>;
   } catch (Exception e) {
       e.printStackTrace();
       setError();
   }
 if (echoOutput)
	   super.write(B)/>/>;
} // end write()

// PrintStream override.
public void write(byte buf[], int off, int len) {
   try {
	   logfile.write(buf, off, len);
   } catch (Exception e) {
       e.printStackTrace();
       setError();
   }
 if (echoOutput)
	   super.write(buf, off, len);  
}  // end write()

//-------------------------------------------------------------------
// Following for testing SaveStdOutput class: Comment out when done!
/*
public static void main(String[] args) {
   try {
       // Start capturing characters into the log file.
       SaveStdOutput.start("log.txt");

       // Test it.
       System.out.println("Here's is some stuff to stdout. " 
                               + new java.util.Date());
       System.err.println("Here's is some stuff to stderr.");
       System.out.println("Let's throw an exception...");
       new Exception().printStackTrace();
       throw new Exception("this is thrown");
   } catch (Exception e) {
       e.printStackTrace();
   } finally {
       // Stop capturing characters into the log file 
       // and restore old setup.
       SaveStdOutput.stop();
   }
   System.out.println("This should be to console only!");
} // end main() */
}  // end class SaveStdOutput



For catching exceptions:
Define this in the class:
    private Thread.UncaughtExceptionHandler lastUEH = null;  // For trapping exceptions

    //----------------------------------------------------
    // Define inner class to handle exceptions
    class MyExceptionHandler implements Thread.UncaughtExceptionHandler {
        public void uncaughtException(Thread t, Throwable e){
           java.util.Date dt =  new java.util.Date();
           String fn = rootDir + "/WakeUp_" + sdf.format(dt) + "_Trace.txt";   // 2014-02-02T193504
           try{ 
              PrintStream ps = new PrintStream( fn );
              e.printStackTrace(ps);
              ps.close();
              System.out.println("ScrnOnOffSrcv  wrote trace to " + fn);
              e.printStackTrace(); // capture here also???
              SaveStdOutput.stop(); // close here vs calling flush() in class  ???
           }catch(Exception x){
              x.printStackTrace();
           }
           lastUEH.uncaughtException(t, e); // call last one  Gives: "Unfortunately ... stopped" message
           return;    //???? what to do here
        }
     }


Put this in onCreate():
	        // Set trap for exceptions
	         lastUEH = Thread.getDefaultUncaughtExceptionHandler(); // save previous one
	         Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());



Is This A Good Question/Topic? 0
  • +

Page 1 of 1