为什么System.out.println"在Android上工作?

我想在控制台打印一些东西,这样我就可以调试它。但出于某种原因,我的Android应用程序没有打印任何东西。

我怎么调试呢?

public class HelloWebview extends Activity {
WebView webview;
private static final String LOG_TAG = "WebViewDemo";
private class HelloWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
webview = (WebView) findViewById(R.id.webview);
webview.setWebViewClient(new HelloWebViewClient());
webview.getSettings().setJavaScriptEnabled(true);
webview.setWebChromeClient(new MyWebChromeClient());
webview.loadUrl("http://example.com/");
System.out.println("I am here");
}
271487 次浏览
< p > 更正: < p > 在模拟器和大多数设备上,System.out.println被重定向到LogCat并使用Log.i()打印。这在非常老的或自定义的Android版本上可能不是真的。< / p > < p > 原: < p > 没有控制台来发送消息,所以System.out.println消息会丢失。当你使用javaw.

运行一个“传统”Java应用程序时,同样会发生这种情况

相反,你可以使用Android Log:

Log.d("MyApp","I am here");

然后,您可以在Eclipse中的Logcat视图中查看日志,或者运行以下命令:

adb logcat

最好养成查看logcat输出的习惯,因为这也是任何未捕获异常的堆栈跟踪显示的地方。

每个日志调用的第一个条目是标识日志消息来源的日志标记。这很有帮助,因为您可以过滤日志的输出,只显示您的消息。为了确保你与你的日志标签是一致的,最好在某个地方将它定义为static final String

Log.d(MyActivity.LOG_TAG,"Application started");

Log中有五个单字母方法,对应于以下级别:

  • e()错误
  • w() -警告
  • i() -信息
  • d() -调试
  • v() - Verbose
  • wtf() -多么可怕的失败

文档说明了以下关于级别的内容:

除非在开发期间,否则决不应该将Verbose编译到应用程序中。调试日志在运行时被编译,但在运行时被剥离。错误、警告和信息日志总是被保存。

使用日志类。输出与LogCat可见

是的。如果你正在使用模拟器,它将显示在Logcat视图的System.out标签下。编写一些东西并在模拟器中进行尝试。

当然,要在logcat中查看结果,你至少应该将Log级别设置为"Info" (logcat中的日志级别);否则,就像我遇到的那样,您将看不到您的输出。

在你的手机上没有地方可以读取System.out.println();

相反,如果你想查看某个结果,要么查看你的logcat/console窗口,要么让一个ToastSnackbar(如果你在较新的设备上)出现在设备的屏幕上,并显示消息:) 这就是当我必须检查它在switch case代码中的位置时所做的事情!祝你编码愉快!:) < / p >

如果你真的需要System.out.println工作(例如。它是从第三方库调用的)。你可以简单地使用反射来更改System.class中的out字段:

try{
Field outField = System.class.getDeclaredField("out");
Field modifiersField = Field.class.getDeclaredField("accessFlags");
modifiersField.setAccessible(true);
modifiersField.set(outField, outField.getModifiers() & ~Modifier.FINAL);
outField.setAccessible(true);
outField.set(null, new PrintStream(new RedirectLogOutputStream());
}catch(NoSuchFieldException e){
e.printStackTrace();
}catch(IllegalAccessException e){
e.printStackTrace();
}

RedirectLogOutputStream类:

public class RedirectLogOutputStream extends OutputStream{
private String mCache;


@Override
public void write(int b) throws IOException{
if(mCache == null) mCache = "";


if(((char) b) == '\n'){
Log.i("redirect from system.out", mCache);
mCache = "";
}else{
mCache += (char) b;
}
}
}

System.out.println("…")会显示在Android Studio的Android Monitor上

我将把这个留给进一步的访问者,因为对我来说,这是关于主线程无法System.out.println的事情。

public class LogUtil {


private static String log = "";
private static boolean started = false;
public static void print(String s) {
//Start the thread unless it's already running
if(!started) {
start();
}
//Append a String to the log
log += s;
}


public static void println(String s) {
//Start the thread unless it's already running
if(!started) {
start();
}
//Append a String to the log with a newline.
//NOTE: Change to print(s + "\n") if you don't want it to trim the last newline.
log += (s.endsWith("\n") )? s : (s + "\n");
}


private static void start() {
//Creates a new Thread responsible for showing the logs.
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while(true) {
//Execute 100 times per second to save CPU cycles.
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
//If the log variable has any contents...
if(!log.isEmpty()) {
//...print it and clear the log variable for new data.
System.out.print(log);
log = "";
}
}
}
});
thread.start();
started = true;
}
}

用法:LogUtil.println("This is a string");

最近我在Android Studio 3.3中发现了同样的问题。我关闭了其他Android工作室项目,Logcat开始工作。上面这个公认的答案根本不符合逻辑。

它没有显示在您的应用程序中…它在模拟器的logcat下

我没有花哨的IDE使用LogCat,因为我使用一个移动IDE。

我必须使用各种其他方法,我有类和实用程序供您使用,如果您需要的话。

    <李> < p >类jav.android.Msg。有一个静态方法的集合。 答:打印机器人吐司的方法。 B:弹出对话框的方法。 每个方法都需要一个有效的Context。

    .

    . 一个更有野心的方式,一个Android控制台。你在你的应用程序中实例化一个控制台句柄,它会启动控制台(如果它已经安装),你可以写入控制台。我最近更新了控制台以实现从控制台读取输入。它直到接收到输入才返回,就像普通的控制台一样。 A:下载并安装Android控制台(找我拿) B:附带一个java文件(java .android.console. iconsole)。将它放在适当的目录中。它包含了操作Android控制台的方法。 C:调用完成初始化的构造函数。 D: read< *比;并编写控制台。 还有工作要做。也就是说,因为onserviceconnconnected没有被立即调用,你不能在实例化它的同一个函数中使用IConsole
  1. 在创建Android控制台之前,我创建了控制台对话框,这是一个在同一应用程序中操作的对话框,类似于控制台。优点:不需要等待onserviceconnconnected使用它。缺点:当应用程序崩溃时,你不会得到应用程序崩溃的消息。

由于Android控制台是一个单独的应用程序在一个单独的进程,如果你的应用程序崩溃,你肯定会看到错误。此外,IConsole在你的应用程序中设置了一个未捕获的异常处理程序,以防你不热衷于异常处理。它几乎打印堆栈跟踪和异常消息到Android控制台。最后,如果Android控制台崩溃,它会将堆栈跟踪和异常发送给你,你可以选择一个应用程序来读取它。实际上,AndroidConsole并不需要崩溃。

< em > <强>编辑临时演员 < / >强 我注意到我的APK Builder没有LogCat;助手。然后我意识到无论如何使用我的Android控制台的好处

  1. Android控制台被设计成只占据屏幕的一部分,所以你可以看到你的应用程序,以及应用程序发送到控制台的数据。这在AIDE中是不可能的。我想触摸屏幕,看到坐标,Android控制台让这很容易。

  2. Android控制台被设计为当你写入它时弹出。

  3. Android控制台将隐藏当你反按。

对我有效的解决方案:

Logcat之下。(如果尚未显示Logcat,则显示Logcat。点击查看菜单—>工具窗口—>Logcat)。它显示为System。不是像你期望的那样System.out.println。重建应用程序,如果你还没有。

在图中,黄色突出显示表示系统。输出“Hello again”。

enter image description here