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 打印消息。
我遇到了一个奇怪的问题。我已经浪费了很多时间去理解 并解决这个问题,但没有任何效果。
我有一个应用程序可以通过蓝牙连接与另一台设备通信 接收一些传感器数据。到那时,一切正常,我可以连接 到设备,接收和处理消息。
但是昨天,我决定创建某种日志文件直接保存在 内部存储器从设备接收到的数据,没有从我的应用程序进行任何类型的转换。
为了从设备接收数据,我有一个后台线程:
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 打印消息。