如何在我的模拟器中的应用程序中查看连续的logcat

时间:2011-11-04 23:55:24

标签: android android-logcat

我刚刚获得前30行,如何查看我的应用程序中生成的新行,这是我的代码:

package com.example.showinlog;


public class ShowingLog extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        try {
            Process process = Runtime.getRuntime().exec("logcat");
            BufferedReader bufferedReader = new BufferedReader(
            new InputStreamReader(process.getInputStream()));

            StringBuilder log=new StringBuilder();
            String line; 
            while ((line = bufferedReader.readLine()) != null) {

              log.append(line);
              log.append("\n");

            }
            TextView tv = (TextView)findViewById(R.id.textView1);
            tv.setText(log.toString());
          } catch (IOException e) {
          }
    }
}

2 个答案:

答案 0 :(得分:2)

我实际上不确定你是怎么得到的。读取不应该“结束”,并且由于您不在另一个线程中进行读取,因此您永远不应该进入初始化TextView的部分。

即使您确实可以连续记录文本,但它也无法使用此代码,因为您永远不会“完成”构建StringBuilder。

试试这个。您需要传入LogcatOut作为日志数据的回调:

public class LolCat
{
    private Process proc;
    private LogcatOut logcatOut;

    public LolCat(LogcatOut logcatOut)
    {
        this.logcatOut = logcatOut;
    }

    private InputStream inStd;

    private InputStream inErr;

    private LogcatProcessStreamReader streamReader;
    private LogcatProcessStreamReader errStreamReader;

    public void start()
    {
        try
        {
            proc = Runtime.getRuntime().exec("logcat");
            OutputStream os = proc.getOutputStream();

            this.inStd = proc.getInputStream();
            this.inErr = proc.getErrorStream();

            startReaders();

            os.flush();
        }
        catch (IOException e)
        {
//            App.logExecption("Can't logcat", e);
        }
        catch (Exception e1)
        {
//            App.logExecption("Can't logcata", e1);
        }
    }

    private void startReaders() throws FileNotFoundException
    {
        this.streamReader = new LogcatProcessStreamReader(this.inStd, logcatOut);
        this.errStreamReader = new LogcatProcessStreamReader(this.inErr, null);

        streamReader.start();
        errStreamReader.start();
    }

    public void kill()
    {
        proc.destroy();
        if (this.streamReader != null)
            this.streamReader.finish();
        if (this.errStreamReader != null)
            this.errStreamReader.finish();
    }

    public abstract class LogcatOut
    {
        public abstract void writeLogData(byte[] data, int read) throws IOException;
        protected void cleanUp()
        {

        }
    }

    class LogcatProcessStreamReader extends Thread
    {
        private InputStream in;
        private boolean done = false;
        private LogcatOut logcatOut;

        public LogcatProcessStreamReader(InputStream in, LogcatOut logcatOut)
        {
            this.in = in;
            this.logcatOut = logcatOut;
        }

        @Override
        public void run()
        {
            byte[] b = new byte[8 * 1024];
            int read;

            try
            {
                while (!done && ((read = in.read(b)) != -1))
                {
                    if(logcatOut != null)
                        logcatOut.writeLogData(b, read);
                }

                if(logcatOut != null)
                    logcatOut.cleanUp();
            }
            catch (IOException e)
            {
//                App.logExecption("Can't stream", e);
            }
        }

        public synchronized void finish()
        {
            done = true;
        }
    }
}

在你的onCreate:

    final Handler handler = new Handler();
    new LolCat(new LolCat.LogcatOut()
    {
        @Override
        public void writeLogData(final byte[] data, final int read) throws IOException
        {
            handler.post(new Runnable()
            {
                public void run()
                {
                    TextView tv = (TextView) asdf;
                    tv.setText(tv.getText() + "\n" + new String(data, 0, read));

                }
            });
        }
    });

一些警告:

1)我从其他代码中改编了这个。我没有测试过它。您可能会遇到空指针异常等,但基本代码应该可以正常工作。

2)你确实需要日志权限(忘记那是什么)

3)我不记得日志数据是来自std out还是err out。我认为它是std,但如果你什么也没得到,那就换掉吧。

4)我不建议在文本视图中像我在这里那样连接文本。您需要实现一个可以限制的缓冲区,并且Java中的大型字符串连接显然很糟糕。我会把这个解决方案留给读者......

答案 1 :(得分:2)

我发现AsyncTasks在尝试实现时非常有用。

public class LogCatTask extends AsyncTask<Void, String, Void> {    
    public AtomicBoolean run = new AtomicBoolean(true);

    @Override
    protected Void doInBackground(Void... params) {
        try {
            Runtime.getRuntime().exec("logcat -c");
            Process process = Runtime.getRuntime().exec("logcat");
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            StringBuilder log = new StringBuilder();
            String line = "";
            while (run.get()) {
                line = bufferedReader.readLine();
                if (line != null) {
                    log.append(line);
                    publishProgress(log.toString());
                }
                line = null;
                Thread.sleep(10);
            }
        }
        catch(Exception ex){

        }
        return null;
    }
}

要执行任务,您可以执行类似

的操作
public void setupTextView(){
    textView.setMovementMethod(new ScrollingMovementMethod());
    logCatTask = new LogCatTask(){
        @Override
        protected void onProgressUpdate(String... values) {
            textView.setText(values[0]);
            super.onProgressUpdate(values);
        }
    };
    logCatTask.execute();
}