Need to Capture selective STDOUT from Android for display in listview(需要从 Android 捕获选择性 STDOUT 以在列表视图中显示)
问题描述
我正在使用自定义逻辑库在 Android 中运行嵌入式库 [tuProlog (2p.jar)] Prolog 推理引擎,我可以在 Android ListView 中成功查询和显示(部分)结果.
I'm running the an embedded library [tuProlog (2p.jar)] Prolog Inference Engine in Android with custom logic bases which I can successfully query and display (some) of the results in an Android ListView.
显示的只是推理引擎本身的结果,而不是像 Prolog 'write' 语句(默认情况下)写入 STDOUT 的辅助命令.
What gets displayed is only the results from the inference engine itself, not ancillary commands like a Prolog 'write' statement which (by default) writes to STDOUT.
我需要在 Android 变量中捕获写入"打印到 STDOUT 的结果以显示给用户.总的想法(我没有与 ListView 结婚来实现)是模拟命令行交互,如果他们运行基于 Java 的 Prolog Interpreter 终端界面,则会进行该交互.
I need to capture the result of that 'write' printing to the STDOUT in an Android variable to display to the user. The general idea (which I'm not married to a ListView to implement) is to simulate the command line interaction which one would engage in if they ran a Java Based Prolog Interpreter terminal interface.
为了完成这个项目,我想坚持知识工程领域,而不是进入系统工程领域,所以我将不胜感激任何对此问题的见解.
I'd like to stick to the realm of Knowledge Engineering rather than entering Systems Engineering in order to complete this project, so I would be grateful for any insights into this problem.
我的研究使我这里作为进一步研究的途径,但是系统的东西很快就超出了我的经验.
My research has lead me here as an avenue of further study, but the systems stuff quickly gets past my experience.
提前非常感谢....
推荐答案
经过我自己的一些研究和与 tuProlog 开发人员的进一步讨论,我有一个解决方案,我认为值得与这个社区分享...
After a good bit of my own research and further discussions w/the tuProlog developers I have a solution to this question I think is worth sharing w/this community...
问题的总体背景是ANY Prolog 实现在正确"Android 上工作,作为以后更有趣的应用程序(专家系统、游戏 AI 和自然语言界面)的基础架构下线.
The overall context of the issue is getting ANY Prolog implementation to work on 'properly' Android as a foundational architecture for more interesting Apps (Expert Systems, Game AI, and Natural Language Interfaces) later on down the line.
最大的障碍是 Prolog 是一个基于控制台"的解释性环境,它打印到 STDOUT,虽然 Android 允许控制台打印活动,但默认情况下它将所有这些都发送到 /dev/null.
The big hurdle is that Prolog is a 'Console' based interpretative environment which prints to STDOUT, and while Android tolerates console printing activities, by default it routs ALL of that to /dev/null.
因此有 两 组问题需要解决:(1) 是否有 任何 Prolog 可移植到Android 环境,以及(2)当控制台输出路由到 /dev/null 时,如何正确"处理捕获控制台输出的问题>.
So there are two sets of problems to address: (1) Is there ANY Prolog portable to the Android Environment, and (2) How does one 'properly' handle the issue of capturing the console output when it's routed to /dev/null.
地址 (1):我们选择了 tuProlog Site,官方出处可见:谷歌代码库 - tuProlog.他们将 prolog 设计为嵌入到单个 JAR 文件中,特别适用于 Android.他们是我们发现的唯一一个这样做的人,他们对开发人员响应".他们的东西是Open Source Java/Android,他们有一个Android Prolog 应用程序,很快就会更新.询问他们的代码对于找到合适的解决方案非常宝贵.
Addressing (1): We settled on tuProlog Site, who's official source can be found: Google Code Repository - tuProlog. They have engineered prolog to be embedded by a single JAR file particularly for Android. They were the only one we found who did it, and they are 'responsive' to developers. Their stuff is Open Source Java/Android and they have an Android Prolog App out with an update coming soon. Interrogating their code was invaluable to finding a proper solution.
地址 (2):为本研究增加最大价值的链接如下:从 PrintStream 读取, 将 Java OutputStream 转换为 InputStream,最终是最有用的 StreamWriter 到 OutputStream.
Addressing (2): The links which added the most value to this research are these: Reading from PrintStream, Convert Java OutputStream to InputStream, and ultimately the most useful StreamWriter to OutputStream.
具体来说,需要做的是:
- 创建一个 ByteArrayOutputStream 对象来捕获二进制数据从打印过程到控制台(System.out).
- 在中创建 PrintStream 对象(使用 ByteArrayOutputStream)设置 System.setOut(控制控制台输出 [System.out.println] 的位置)
- 重新路由系统输出
- 捕获所需的控制台打印输出到字符串变量
- 将该字符串添加(在此 Android 项目的情况下)到列表视图的一行
- 通知 Listview 数据已更改
- 重置 ByteArrayOutputStream 对象(以避免串联)
- Create a ByteArrayOutputStream object to capture the Binary Data from the process of printing to the Console (System.out).
- Create PrintStream object (using the ByteArrayOutputStream) in which to set the System.setOut (which governs where the console output [System.out.println] goes to)
- Reroute the System Output
- Capture the desired console print output to a string variable
- Add that string (in the case of this Android project) to a row of a listview
- Notify that Listview the Data has changed
- Reset the ByteArrayOutputStream object (to avoid concatenation)
这是代码:
// 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 考虑了控制台打印问题并围绕它设计了这个特定的实现,使用侦听器和事件的组合来正确解决 PrologWrite"命令的捕获以及其他问题.
Final Notes: tuProlog took into consideration the console printing problem and designed this particular implementation around it, using a combination of Listeners and Events to properly work around the capturing of Prolog "Write" commands as well as other.
Strict Prolog Queries 的解决可以通过仔细阅读他们的用户指南中建立的首选方法相当容易地完成......开发人员可以从中快速找到他们需要的东西.
The solving of Strict Prolog Queries is accomplished fairly easily by perusing the preferred methods established in their users guide ... developers can quickly gleam what they need from that.
这是对 Prolog Engine 函数的捕获,例如 Write、Spy 和 Error 事件,这些事件更难确定(我最终咨询了 w/开发人员).为此,您需要询问他们的 CUIConsole 的 Android 实现(与他们的 CUIConsole 的控制台实现相反,后者不同").
It's the capturing of Prolog Engine functions like the Write, Spy and Error Events that are harder to nail down (I eventually consulted w/the developers). For that you'll need to interrogate their Android Implementation of CUIConsole (as opposed to their Console implementation of CUIConsole , which 'is' different).
简而言之,答案是:(a) 建立一个监听器,然后(b) 为事件做准备 发生.
In a nutshell the answer is this: (a) establish a Listener and then (b) prepare for the event to take place.
代码如下:
// 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 **
");
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 **
");
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 **
");
myChatListItems.add( e.getMsg() );
chatBotAdapter.notifyDataSetChanged();
}
结束说明:对于那些有兴趣的人 Android 上的 Prolog",我很乐意提供我编写的任何代码或我拥有的资源,以便在此过程中为您提供帮助.请不要犹豫.
End Note: For those interested in doing "Prolog on Android", I'd be very happy to make available any code I write or resource I have in order to help you along this process. Please don't hesitate to ask.
这篇关于需要从 Android 捕获选择性 STDOUT 以在列表视图中显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!