logcat 中未打印日志

Logs don't get printed in the 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);
        }
    }
}

这个线程工作得很好,当收到一条消息时,它会通知听众, 我的控制器 class。当收到消息时,我尝试做的第一件事就是保存它:

public class Controller implements CommunicationThread.CommunicationListener

    ...

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

}

这是 LogCreator class:

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 class 已经初始化并且可以正常工作,因为 如果我稍后尝试读取文件,一切都在那里。

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

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

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

未打印日志:

通信线程:

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

控制器:

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

日志创建器:

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 的和停止方法都是从主线程而不是 CommunicationThread 调用的,并且这两种方法都打印了它们的日志。正因为如此,在onMessageReceived方法中 控制器 class,我试过这个:

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

但是,不幸的是,logcat 中没有打印日志。吐司还在 执行,数据仍然保存到文件中。

如果有人知道可能导致此问题的原因,我真的很想知道,谢谢。

我终于自己找到了解决办法。我不清楚以下内容不起作用的原因,IMO 应该将其视为错误。

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

示例:"15.50\r"

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

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

没有打印任何内容,我们也没有收到任何警告。

但是,如果我改为这样做:

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

其中数据为: "15.50\r"

一切正常,logcat 打印消息。