» Программирование Android

Доступ к аварийному логу на Android

Даже самые стабильные, хорошо протестированные и надежные приложения время от времени могут «падать», причем часто тогда, когда совершенно этого не ожидаешь. Причины могут быть самыми разными, но факт таков – тщательно проработанное и протестированное приложение может в итоге совершенно непредсказуемо повести себя на некоторых моделях Android-девайсов, в то время как на других оно работает без «сучка и задоринки».

Для анализа ошибок в операционной системе Windows предусмотрен, например, аварийный мини-дамп. Такой механизм помогает разработчику провести максимальную отладку своего творения. Однако на Android всё несколько сложнее.

Для данных целей созданы некоторые готовые решения, например Android Log Collector, однако они обычно не совсем полноценны и собирают информацию не полностью или имеют другие ограничения. Поэтому в данной статье мы попытаемся создать собственную утилиту для доступа к аварийному логу.

Итак, класс LogCatWrapperBackgroundTask воспроизводится отдельным потоком AsyncTask, и его задача заключается в запуске logcat. Последняя функция как раз и записывает лог системы в указанный файл. Поэтому для работы прописываем в AndroidManifest.xml соответствующее разрешение:
            <uses-permission android:name=»android.permission.READ_LOGS» />

 

            public class LogCatWrapperBackgroundTask extends AsyncTask<ArrayList<String>, Void, StringBuilder>{

 

       @Override

        protected void onPreExecute(){

 

        }

 

        @Override

        protected StringBuilder doInBackground(ArrayList<String>… params){

            final StringBuilder log = new StringBuilder();

            try{

                ArrayList<String> commandLine = new ArrayList<String>();

                commandLine.add(«logcat»);

                ArrayList<String> arguments = ((params != null) && (params.length > 0)) ? params[0] : null;

                if (null != arguments){

                    commandLine.addAll(arguments);

                }

 

                // запускаем logcat

                Process process = Runtime.getRuntime().exec(commandLine.toArray(new String[0]));

                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));

 

                String line;

                while ((line = bufferedReader.readLine()) != null){

                    log.append(line);

  

                }

            }

            catch (IOException e){

                Log.e(«MyApp», «LogCatWrapperBackgroundTask failed», e);

            }

 

            return log;

        }

 

        @Override

        protected void onPostExecute(StringBuilder log){

 

        }

}

 

            Используется же данный класс запуском LogCatWrapperBackgroundTask при старте приложения, обычно в методе Activity.onCreate:

ArrayList list = new ArrayList();

 

list.add(«-f»);

list.add(«/sdcard/crashdump.log»);

 

new LogCatWrapperBackgroundTask().execute(list);

 

В list указываются все параметры для запуска logcat. Нас интересует параметр –f, который обозначает запись лога в указанный файл (по указанному пути). В файл будет выводиться, если не использоваться фильтры, весь нефильтрованный лог девайса, выводимый в консоль, в том числе аварийные сообщения приложения. Можно также применить и фильтры, для того, чтобы записывать только отдельные элементы системного лога в файл.

После проделанных действий получение аварийного лога сводится к запуску проблемного приложения, воспроизведению ошибки, которая приводит к его падению, и копированию полученного файла, содержащего лог, куда понадобится. Например, можно его отправить разработчику программного обеспечения для дальнейшей отладки приложения. Сам же файл из системы рекомендуется удалять, потому как часто система продолжает записывать в него информацию даже после закрытия программы.