An
important step in any application development - is logging. There are no
serious projects that have been written without at least one bug. The log is
used to keep track of all the moving and changing objects in the application.
For example: requests and responses from the server, the values of arrays and
collections, the output error handlers, and more. Consider how to implement
logging into the application so that it is comfortable.
In Android
there is a class for working c logs: android.util.Log. Which we are going to
use to display the information in LogCat DDMS. But we modify it a bit for
easier use.
First,
every time when we print some information in the log, spent little time. If the
output of the log very often, this time can affect application performance.
Therefore, before the publication of the application, you need to disable all
of our logs. And if a lot of them? In this article we consider a class that
allows you to disable all logging by changing just one parameter.
Second, the
publication of the application is not possible if the application manifest
parameter has set android:debuggable = "true", which we used to keep
track of any part of the code in an application. In this article I will give an
example, how depending on this option to display or not display the information
in the log.
Third, it
is sometimes necessary to override the output log is not in the console, and
the other output. On the example in this article we will try to develop an
application that will display our log to a file on SD-card.
Development
Create a new
class for logging: LogSystem, one attribute of the class that will be
responsible for the ability to output information to the log.
public final class LogSystem { private static boolean mLoggingEnabled = true; private LogSystem() { } public static void setDebugLogging(boolean enabled) { mLoggingEnabled = enabled; } }
Override
all the output methods of the Log class:
public static int v(String tag, String msg) { int result = 0; if (mLoggingEnabled) { result = Log.v(tag, msg); } return result; } public static int v(String tag, String msg, Throwable tr) { int result = 0; if (mLoggingEnabled) { result = Log.v(tag, msg, tr); } return result; } public static int d(String tag, String msg) { int result = 0; if (mLoggingEnabled) { result = Log.d(tag, msg); } return result; } public static int d(String tag, String msg, Throwable tr) { int result = 0; if (mLoggingEnabled) { result = Log.d(tag, msg, tr); } return result; } public static int i(String tag, String msg) { int result = 0; if (mLoggingEnabled) { result = Log.i(tag, msg); } return result; } public static int i(String tag, String msg, Throwable tr) { int result = 0; if (mLoggingEnabled) { result = Log.i(tag, msg, tr); } return result; } public static int w(String tag, String msg) { int result = 0; if (mLoggingEnabled) { result = Log.w(tag, msg); } return result; } public static int w(String tag, String msg, Throwable tr) { int result = 0; if (mLoggingEnabled) { result = Log.w(tag, msg, tr); } return result; } public static int w(String tag, Throwable tr) { int result = 0; if (mLoggingEnabled) { result = Log.w(tag, tr); } return result; } public static int e(String tag, String msg) { int result = 0; if (mLoggingEnabled) { result = Log.e(tag, msg); } return result; } public static int e(String tag, String msg, Throwable tr) { int result = 0; if (mLoggingEnabled) { result = Log.e(tag, msg, tr); } return result; }
We have
developed a a managed log. mLoggingEnabled attribute instructs whether to
display a message or not.
In order to
use our class, you just call any corresponding static method.
Consider
the following example. We want to track the entire application life cycle.
public class MainActivity extends Activity { public static final String TAG = MainActivity.class.getSimpleName(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LogSystem.i(TAG, "onCreate()"); } @Override protected void onDestroy() { super.onDestroy(); LogSystem.i(TAG, "onDestroy()"); } @Override protected void onPause() { super.onPause(); LogSystem.i(TAG, "onPause()"); } @Override protected void onResume() { super.onResume(); LogSystem.i(TAG, "onResume()"); } @Override protected void onStart() { super.onStart(); LogSystem.i(TAG, "onStart()"); } @Override protected void onStop() { super.onStop(); LogSystem.i(TAG, "onStop()"); } }
Debuggable
In order to
print or not to print the information in the log, depending on the value of
attribute android:debuggable, necessary in the method onCreate() in the main
Activity write:
boolean isDebuggable = (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE)); LogSystem.setDebugLogging(isDebuggable);
Log to file
For logging
to a file on SD-card, you first need to add permission to the application
manifest:
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Now the
LogSystem class will modify, so we can show the log to a file.
private
static final String PATH = "sdcard/log.dat";
public static int logInFile(String tag, String msg) { int result = 0; File file = new File(PATH); try { if (!file.exists()) { file.createNewFile(); } String timeLog = new SimpleDateFormat("dd.MM.yy hh:mm:ss").format(new Date()); BufferedWriter bw = new BufferedWriter(new FileWriter(file, true)); bw.append(timeLog+" (" + tag + ")\t" + msg + "\n"); bw.close(); result = 1; } catch (IOException e) { e.printStackTrace(); } return result; }
We have
added a static attribute to specify the path to our log on SD-card. And
developed a method to store the information in the file.
Upgrade our
application with the new changes. Replace LogSystem.i(TAG,
"onCreate()"); в методе onCreate() our Activity on
LogSystem.logInFile(TAG, " onCreate ()");
Example
record in the log will be the next:
19.09.12
14:12:01 (MainActivity) onCreate
()
Possible improvements
- Another way to output to a file
If we want
to use static methods v(), d(), e(), i(), w()to output directly to a file, you
can modify the class LogSystem follows (the example of the method e()):
public static int logInFile(int priority, String tag, String msg) { int result = 0; File file = new File(PATH); try { if (!file.exists()) { file.createNewFile(); } String timeLog = new SimpleDateFormat("dd.MM.yy hh:mm:ss").format(new Date()); BufferedWriter bw = new BufferedWriter(new FileWriter(file, true)); bw.append(priority + "\t" + timeLog + " (" + tag + ")\t" + msg + "\n"); bw.close(); result = 1; } catch (IOException e) { e.printStackTrace(); } return result; } public static int e(String tag, String msg) { int result = 0; if (mLoggingEnabled) { result = logInFile(Log.ERROR, tag, msg); } return result; }
- Improvement output methods
It is also possible to improve the output
methods, for example, add the parameterint placeForLog, which would show where
the log output
public static int e(String tag, String msg, int placeForLog) { int result = 0; if (mLoggingEnabled) { switch (placeForLog) { case 0: result = logInFile(Log.ERROR, tag, msg); break; case 1: result = Log.e(tag, msg); break; } return result; }
No comments:
Post a Comment