【问题标题】:Why doesn't "System.out.println" work in Android?为什么“System.out.println”在 Android 中不起作用?
【发布时间】:2011-01-14 07:13:18
【问题描述】:

我想在控制台打印一些东西,以便调试它。但由于某种原因,我的 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");
    }

【问题讨论】:

  • 虽然你在下面得到了答案,但我想补充一点,SOP 语句的输出也被定向到 LogCat:只有标签名称是 System.out
  • 0.9 System.out 之前丢失了,我想。在它被传递到 logcat 输出之后:code.google.com/p/android/issues/detail?id=92。 (如果您使用现有的库或使用 System.out 的库,无论对错,它都会在更高版本的 Android 的 logcat 中显示。)
  • 我们可以看到logcat里面的System.out.printlns。

标签: java android printing console system


【解决方案1】:

更正:

在模拟器和大多数设备上,System.out.println 被重定向到 LogCat 并使用Log.i() 打印。在非常旧的或自定义的 Android 版本上,这可能不是真的。

原文:

没有将消息发送到的控制台,因此System.out.println 消息会丢失。同样,当您使用 javaw 运行“传统”Java 应用程序时,也会发生这种情况。

相反,您可以使用Android Log class

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() - 详细
  • wtf() - 多么可怕的失败

documentation says the following about the levels:

除非在开发过程中,否则绝不应将详细信息编译到应用程序中。调试日志被编译,但在运行时被剥离。始终保留错误、警告和信息日志。

【讨论】:

  • 其实——System.out 通过 Log.i() 打印到 LogCat。
  • @JosephEarl - 随意使用“编辑”按钮。
  • 还有 Log.wtf() :-)
  • System.out.println 确实显示在 Android Studio 的 Android Monitor 下。这些显示为“I/System.out”
  • 值得注意的是,Log.wtf在使用时会抛出异常。除非有一个从一开始就不应该发生的情况,否则不应该使用它
【解决方案2】:

使用Log class。使用 LogCat 可见的输出

【讨论】:

    【解决方案3】:

    是的。如果您使用的是模拟器,它将显示在 System.out 标记下的 Logcat 视图中。写点东西在你的模拟器上试试。

    【讨论】:

    • 除此答案外,请记住,有时“发生某些事情”并且使用 System.out 不会打印任何输入。如果是这种情况,请尝试关闭并重新启动模拟器。这对我有用。
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

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

      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;
              }
          }
      }
      

      【讨论】:

        【解决方案6】:

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

        【讨论】:

        • 这是 OP “我想在控制台打印一些东西”的第一句话
        【解决方案7】:

        您的手机上没有可以阅读System.out.println();的地方

        相反,如果您想查看某项操作的结果,请查看您的logcat/console 窗口,或者在设备屏幕上显示ToastSnackbar(如果您使用的是较新的设备),并带有信息 :) 这就是我必须检查例如它在switch case 代码中的位置时所做的事情!玩得开心编码! :)

        【讨论】:

        • 当我点击Android Monitor,然后点击logcat,我看到很多很多信息不断被打印出来……应该是这样的吧?那我怎么看自己的调试信息呢?
        • 我只是滚动浏览其他内容并找到它:D
        【解决方案8】:

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

        【讨论】:

          【解决方案9】:

          我会把这个留给更多的访问者,因为对我来说,主线程无法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");

          【讨论】:

          • 读取/写入变量 LogUtil.log 时存在竞争。你应该使用例如条件变量或监视器以同步变量并避免主动等待循环。
          【解决方案10】:

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

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

          1. 类 jav.android.Msg。有一组静态方法。 A:打印android TOASTS的方法。 B:弹出对话框的方法。 每个方法都需要一个有效的上下文。您可以设置默认上下文。

          2. 更雄心勃勃的方式,Android 控制台。您在应用程序中实例化控制台的句柄,该句柄会启动控制台(如果已安装),您可以写入控制台。我最近更新了控制台以实现从控制台读取输入。在收到输入之前不会返回,就像常规控制台一样。 A: 下载并安装 Android 控制台(从我这里获取) B: 附带一个 java 文件(jav.android.console.IConsole)。将其放在适当的目录中。它包含操作 Android 控制台的方法。 C:调用完成初始化的构造函数。 D:读取并写入控制台。 还有工作要做。也就是说,由于不会立即调用 OnServiceConnected,因此您不能在实例化它的同一函数中使用 IConsole。

          3. 在创建 Android 控制台之前,我创建了控制台对话框,这是一个在同一应用程序中运行的对话框,类似于控制台。优点:无需等待 OnServiceConnected 即可使用它。缺点:当应用崩溃时,您不会收到导致应用崩溃的消息。

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

          编辑附加内容 我注意到我的 while APK Builder 没有 LogCat;助手会。然后我意识到无论如何使用我的 Android 控制台是一个专业人士。

          1. Android 控制台设计为仅占用屏幕的一部分,因此您可以看到您的应用以及从您的应用发送到控制台的数据。这在 AIDE 中是不可能的。所以我想触摸屏幕并查看坐标,Android Console 让这一切变得简单。

          2. Android 控制台设计为在您写入时弹出。

          3. 当您按下时,Android 控制台将隐藏。

          【讨论】:

            【解决方案11】:

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-12-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多