为什么“System.out.println”在Android中不起作用?

时间:2010-02-08 09:25:01

标签: java android printing console system

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

11 个答案:

答案 0 :(得分:196)

<强>校正:

在模拟器上,大多数设备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

  

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

答案 1 :(得分:18)

使用Log class。使用LogCat显示输出

答案 2 :(得分:12)

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

答案 3 :(得分:2)

当然,要在logcat中查看结果,您应该将日志级别至少设置为“Info”(Log level in logcat);否则,因为它发生在我身上,你将看不到你的输出。

答案 4 :(得分:2)

如果你真的需要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;
        }
    }
}

答案 5 :(得分:1)

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

相反,如果您想查看某些内容的结果,请查看logcat/console窗口或制作ToastSnackbar(如果您使用的是新设备) )出现在设备的屏幕上,显示消息:) 当我必须检查例如它在switch case代码中的位置时,这就是我的工作!玩得开心! :)

答案 6 :(得分:1)

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

答案 7 :(得分:0)

System.out.println(“...”)显示在Android Studio的Android监视器上

答案 8 :(得分:0)

我将其留给其他访问者,因为对我来说,这是有关主线程无法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");

答案 9 :(得分:0)

当我使用移动IDE时,我没有出色的IDE来使用LogCat。

我不得不使用其他各种方法,并且我有类和实用工具供您使用。

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

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

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

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

编辑其他内容 我注意到我的APK Builder上没有LogCat。助手帮忙。然后我意识到了无论如何都要使用我的Android控制台的专业人士。

  1. Android控制台的设计仅占用屏幕的一部分,因此您既可以看到您的应用程序,又可以看到从您的应用程序向控制台发出的数据。 AIDE无法做到这一点。所以我想触摸屏幕并查看坐标,Android控制台使此操作变得简单。

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

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

答案 10 :(得分:-2)

最近我在Android Studio 3.3中注意到了同样的问题。我刚刚关闭了其他Android Studio项目,Logcat开始工作。以上公认的答案根本不合逻辑。