日志不会在logcat中打印出来

时间:2016-07-16 19:22:43

标签: android logcat android-logcat

我有一个奇怪的问题。我已经失去了很多时间试图理解 并解决这个问题,但没有任何作用。

我有一个应用程序通过蓝牙连接与另一台设备通信 接收一些传感器数据。在这一点上,一切正常,我可以连接 到设备,接收和处理消息。

但昨天,我决定创建某种日志文件直接保存在 内部存储器从设备接收的数据,没有从我的应用程序进行任何转换。

要从设备接收数据,我有一个后台话题:

public class CommunicationThread extends Thread {
    private static final UUID UUID_DEVICE = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    private static final String TAG = CommunicationThread.class.getSimpleName();
    private CommunicationListener mListener;
    private boolean mRunning;
    private BluetoothSocket mBluetoothSocket;
    private InputStream mInputStream;
    private OutputStream mOutputStream;

    public interface CommunicationListener {
        void onMessageReceived(String msg);
    }

    public CommunicationThread(
            @NonNull BluetoothDevice device,
            @Nullable CommunicationListener listener) throws IOException {
        BluetoothSocket socket = device.createRfcommSocketToServiceRecord(UUID_DEVICE);
        socket.connect();
        this.mBluetoothSocket = socket;
        this.mInputStream = socket.getInputStream();
        this.mOutputStream = socket.getOutputStream();
        this.mListener = listener;
    }

    @Override
    public void run() {
        mRunning = true;
        byte[] bytes = new byte[1024];
        int length;
        while (mRunning) {
            try {
                Log.d(TAG, "Waiting for message");
                // read the message (block until receive)
                length = mInputStream.read(bytes);
                String msg = new String(bytes, 0, length);
                Log.d(TAG, "Message: " + msg);
                // Message received, inform the listener
                if (mListener != null)
                    mListener.onMessageReceived(msg);
            } catch (Exception e) {
                Log.e(TAG, "Error reading the message", e);
            }
        }
    }

    public void sendCommand(String msg) {
        try {
            mOutputStream.write((msg).getBytes());
        } catch (Exception e) {
            Log.e(TAG, "Error to send message", e);
        }
    }

    public void stopCommunication() {
        mRunning = false;
        mListener = null;
        try {
            if (mBluetoothSocket != null) {
                mBluetoothSocket.close();
            }
            if (mInputStream != null) {
                mInputStream.close();
            }
            if (mOutputStream != null) {
                mOutputStream.close();
            }

        } catch (IOException e) {
            Log.e(TAG, "Error to stop communication", e);
        }
    }
}

这个线程运行得很好,当收到一条消息时,它会通知监听器, 我的Controller类。当消息传来时,我尝试做的第一件事就是保存它:

public class Controller implements CommunicationThread.CommunicationListener

    ...

    @Override
    public void onMessageReceived(final String msg) {
        Log.d(TAG, "onMessageReceived(msg): " + msg);
        mLogCreator.saveThis(msg);
        ....
    }

}

这是LogCreator类:

public class LogCreator {
    private static final String TAG = LogCreator.class.getSimpleName();
    public static final String LOG_FILE_NAME = "log.txt";
    private final Context mContext;
    private volatile String mTempFullLog;

    public LogCreator(Context context) {
        mContext = context.getApplicationContext();
        File dir = new File(mContext.getFilesDir(), "log_folder");
        if (!dir.exists()) {
            dir.mkdirs();
            File file = new File(dir, LOG_FILE_NAME);
            writeString(file, "");
            Log.d(TAG, "empty file created");
        }
    }

    public void saveThis(final String data) {
        mTempFullLog += "\n" + data;
        Log.d(TAG, "New log: " + data);
    }

    public void start() {
        File dir = new File(mContext.getFilesDir(), "log_folder");
        File file = new File(dir, LOG_FILE_NAME);
        mTempFullLog = readString(file);
        Log.d(TAG, "File: " + file);
        Log.d(TAG, "Temp full log: " + mTempFullLog);
    }

    public void stop() {
        File dir = new File(mContext.getFilesDir(), "log_folder");
        File file = new File(dir, LOG_FILE_NAME);
        writeString(file, mTempFullLog);
        Log.d(TAG, "log saved: " + mTempFullLog);
    }
}

LogCreator类已经初始化,它可以正常工作,因为 如果我稍后尝试阅读该文件,那么一切都在那里。

真正的问题如下:在此期间有很多对Log.d的调用 这个执行流程,这让我很容易理解所有的过程。 但是,日志只会打印在logcat中,直到此Log.d调用为止 CommunicationThread类:

Log.d(TAG, "Waiting for message);

收到消息后,所有代码都正常执行,但没有打印日志 logcat,我真的不知道为什么。

日志未打印:

CommunicationThread:

Log.d(TAG, "Message: " + msg);

控制器:

Log.d(TAG, "onMessageReceived(msg): " + msg);

LogCreator:

Log.d(TAG, "New log: " + data);

就像我说的那样,我知道一切都正常,因为日志 即使没有logcat打印,也会在内部存储器中创建文件。它花了我 几个小时才意识到问题只出现在日志中而不是真正存在 我的代码。

出于测试目的,如果我在LogCreator的saveThis方法中添加此代码, 它正常执行:

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        Toast.makeText(mContext, data, Toast.LENGTH_SHORT).show();
    }
});

这让我觉得一切都可能是线程问题,因为一开始 LogCreator的stop方法都是从主线程而不是CommunicationThread调用的,两种方法都打印了日志。因此,在onMessageReceived方法中 在Controller类中,我尝试了这个:

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        mLogCreator.saveThis(msg);
    }
});

但是,不幸的是,日志不会在logcat中打印出来。吐司还在 已执行,数据仍保存到文件中。

如果有人知道可能导致这种情况的原因,我真的很想知道,谢谢。

1 个答案:

答案 0 :(得分:0)

我终于找到了解决方案。以下不起作用的原因对我来说并不清楚,IMO它应该被视为一个bug。

我在调试模式下编译应用程序并发现从设备收到的字符串有一个" \ r"最后。

示例:"15.50\r"

所以,出于一些奇怪的原因,如果我尝试这样做:

Log.d(TAG, "New log: " + data);

什么都没打印,我们根本没有收到任何警告。

但是,如果我这样做:

Log.d(TAG, "New log: " + data.replace("\r", ""));

数据位于: "15.50\r"

一切正常,logcat打印消息。