Необходимо захватить выборочный STDOUT с Android для отображения в списке - PullRequest
4 голосов
/ 13 января 2012

Я использую встроенную библиотеку [tuProlog (2p.jar)] Prolog Inference Engine в Android с пользовательскими логическими базами, которые я могу успешно запрашивать и отображать (некоторые) результаты в Android ListView.

Отображаются только результаты самого механизма вывода, а не вспомогательные команды, такие как оператор записи Prolog, который (по умолчанию) записывает в STDOUT.

Мне нужно записать результат этой «записи» печати в STDOUT в переменной Android для отображения пользователю. Общая идея (которую я не женат для реализации ListView) состоит в том, чтобы моделировать взаимодействие командной строки, в которое можно было бы вступить, если бы они запускали интерфейс терминала Java на основе интерпретатора Prolog.

Я бы хотел придерживаться области инженерии знаний, а не заниматься системной инженерией, чтобы завершить этот проект, поэтому я был бы благодарен за любое понимание этой проблемы.

Мои исследования привели меня здесь в качестве пути дальнейшего изучения, но системный материал быстро проходит мимо моего опыта.

Большое спасибо заранее ....

1 Ответ

4 голосов
/ 18 января 2012

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

Общий контекст проблемыполучает ЛЮБУЮ реализацию Prolog для работы на «должном» Android как основополагающей архитектуре для более интересных приложений (экспертные системы, игровой AI и интерфейсы на естественном языке) в дальнейшем.

Большим препятствием является то, что Prolog является интерпретирующей средой, основанной на консоли, , которая печатает в STDOUT, и, хотя Android допускает консольную печать, по умолчанию ВСЕ это перенаправляется на /dev/null.

Таким образом, существует два набора проблем для решения : (1) Есть ли ЛЮБОЙ Пролог, переносимый в среду Android, и (2) Как «правильно» решить проблему захвата вывода консоли , когда он перенаправлен на / dev/ нуль .

Адресация (1) : Мы остановились на tuProlog Сайт , официальный источник которого можно найти: Google Code Repository - tuProlog.Они разработали пролог для встраивания в один JAR-файл, особенно для Android.Мы были единственными, кто нашел это, и они «отзывчивы» на разработчиков.У них есть с открытым исходным кодом Java / Android , и у них есть Android Prolog App с обновлением в ближайшее время. Запрос их кода был неоценим для нахождения правильного решения.

Адресация (2) : ссылки, которые добавили наибольшую ценность этому исследованию, таковы: Чтение из PrintStream , Преобразование Java OutputStream в InputStream и, в конечном итоге, самый полезный StreamWriter в OutputStream .

В частности, необходимо сделать :

  • Создать объект ByteArrayOutputStream для захвата двоичных данных из процесса печатив консоль ( System.out ).
  • Создать PrintStream объект (с помощью ByteArrayOutputStream), в котором можно установить System.setOut (который определяет, куда выводится консольный вывод [ System.out.println ])
  • Reroute системный вывод
  • Захват желаемоговывод на консоль в строковую переменную
  • Добавить эту строку (в случае этого проекта Android) в строку списка
  • Уведомитьчто Listview Данные изменились
  • Сброс объекта ByteArrayOutputStream (чтобы избежать конкатенации)

Вот код :

   // OutPutStream I/O Experimental Stuff
   PrintStream orgStream   = System.out;

   // ByteArray Sub Experimental Stuff
   ByteArrayOutputStream baos = new ByteArrayOutputStream();
   PrintStream psout = new PrintStream(baos, Boolean.TRUE); // Using autoFlush


   // Instantiate an instance of the Prolog Engine. 
   //Do this only once because it's VERY expensive.
   Prolog engine;


    // ReRouting Print Streams 
    // (Inside method we need to capture console output)
    System.setOut(orgStream);           // Set the System Output Stream  


    String myResult = baos.toString();      // returns the actual text 
    myChatListItems.add(myResult);          // Add Text to New ListView Row  
    chatBotAdapter.notifyDataSetChanged();  // notify the Adapter to Refresh
    baos.reset();                           // Reset the ByteArrayOutputStream

      System.setOut(orgStream);  // RESET the System Output Stream 

Заключительные замечания : tuProlog принял во внимание проблему печати консоли иподписал эту конкретную реализацию вокруг нее, используя комбинацию Listeners и Events для правильной работы с захватом команд Prolog « Write », а также других.

Решение Strict Prolog Queries достигается довольно легко, благодаря изучению предпочтительных методов, установленных в их руководстве пользователя ... разработчики могут быстро высказать то, что им нужно от этого,

Это захват функций Prolog Engine, таких как Запись , Шпион и Ошибка События, которые сложнее зафиксировать (в конце концов я обратился к/ разработчики).Для этого вам нужно будет запросить их реализацию Android CUIConsole (в отличие от их реализации консоли CUIConsole , которая «отличается»).

В двух словах ответ таков: (a) установить слушателя и затем (b) подготовиться к событию состоится.

Вот код:

    // Establish Prolog engine and it's appropriate listeners
    // [Warning, Output, and Spy] 
    engine = new Prolog();
    engine.addWarningListener(this);
    engine.addOutputListener(this);
    engine.addSpyListener(this); 

//// PROLOG CONSOLE OUTPUT MECHANISMS *******************************

@Override
public void onSpy(SpyEvent e) {
    Log.d(TAG, "** LG'd onSpy => SpyEvent Occured ** " );
    System.out.println("** onSpy => SpyEvent Occured ** \n ");
    myChatListItems.add( e.getMsg() );
    chatBotAdapter.notifyDataSetChanged();

}


@Override
public void onOutput(OutputEvent e) {
    Log.d(TAG, "** LG'd: onOutput => OutputEvent Occured ** " );
    System.out.println("** onOutput => OutputEvent Occured ** \n ");
    myChatListItems.add( e.getMsg() );
    chatBotAdapter.notifyDataSetChanged();

}


@Override
public void onWarning(WarningEvent e) {
    Log.d(TAG, "** LG'd: onWarning => WarningEvent Occured ** " );
    System.out.println("** onWarning => WarningEvent Occured ** \n ");
    myChatListItems.add( e.getMsg() );
    chatBotAdapter.notifyDataSetChanged();

}

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

...