2016-07-16 12 views
0

이상한 문제가 있습니다. 나는 이미 많은 시간을 잃어버린 을 이해하려고 노력했지만이 문제는 해결되지 않았다.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); 
     } 
    } 
} 

이 스레드가 꽤 잘 작동하고 메시지가 수신 될 때, 그것은 청취자, 내 컨트롤러 클래스를 알려줍니다

장치로부터 데이터를 수신하기 위해, 나는 백그라운드 스레드가 있습니다. 여기
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에 대한 호출이 많이 있으며, 이로 인해 모든 프로세스를 이해하기가 매우 쉽습니다. 는하지만, 로그에만 CommunicationThread 클래스에서,이 Log.d 호출 될 때까지 로그 캣로 인쇄됩니다

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

메시지가 수신되면, 모든 코드는 일반적으로 실행되지만 로그 로그 캣에 인쇄됩니다 그리고 나는 정말로 이유를 모른다.

로그가 인쇄되지 :

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의 메소드는 모두 CommunicationThread가 아니라 메인 스레드에서 호출되며 두 메소드 모두 로그가 인쇄됩니다.

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

그러나이 불행하게도, 로그는 로그 캣에 인쇄되지 않습니다 때문에, 컨트롤러 클래스의 onMessageReceived 방법 , 나는이 시도. 토스트는 여전히 이며 실행 된 데이터는 여전히 파일에 저장됩니다.

누군가가이 문제를 일으킬 수있는 아이디어가 있다면 정말 감사드립니다.

+0

당신은 프로 가드를 사용하고 있습니까? – Zoe

+0

아니요 프로 가드가 없습니다. – Luiz

+0

전화가 왔습니까? – Zoe

답변

0

마침내 직접 해결책을 찾았습니다. 다음과 같은 것이 작동하지 않는 이유는 분명하지 않으며 IMO는 버그처럼 취급해야합니다.

디버그 모드에서 앱을 컴파일하고 기기에서받은 문자열에 끝에 "\ r"이 있는지 확인합니다.

예 : 나는이 작업을 수행하려고하면 "15.50\r"

그래서, 어떤 이상한 이유 :

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

아무것도 인쇄를 우리는 전혀 경고를받지 않습니다.

그러나, 나는이 대신 할 경우 :

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

데이터는 다음과 같습니다"15.50\r"

모든 작품과 로그 캣 메시지를 인쇄합니다.