마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

블루투스 수신 속도 관련 질문입니다

0 추천

안녕하세요.

임베디드 디바이스랑 연동할 어플을 만들고 있습니다.

임베디드 디바이스에서는 초당 50 패킷을 모바일로 송신하고 있습니다.(향후 최대 1000 패킷으로 올릴수도 있어요)

하나의 패킷은 아래와 같이 5바이트로 되있습니다.

 

헤더 | dat1High | dat1Low | dat2High | dat2Low

 

데이터가 12비트짜리 2종류라 패킷구성을 위와 같이 했어요.

 

송신한것을 제대로 수신하는것까지는 확인을 했는데 문제가...

CPU 점유율이 너무 높고 약간의 딜레이가 생깁니다.

디바이스를 몇개 테스트 해봤는데 갤럭시탭 7인치같은 경우는 점유율이 50%를 먹더라구요...

초당 50개면 분명 많은것은 아닌거같은데 말이죠.

 

처리방식은
 1. 문자열로 변환한 후 처리

 2. byte 배열로 처리

이 2개를 다 해봤는데 속도는 비슷하게 느립니다.

 

코드는 byte 배열로 한것 중 수신, 파싱부분 위주로 아래다 옮길테니 혹시 효율적인 방법 알고계시다면 부탁드립니다.

 

public void run() {
    Log.i(TAG, "BEGIN mConnectedThread");
    byte[] buffer = new byte[100000];
    int bytes;

    int dat1;
    int dat2;   

    ByteBuffer TempByteArrayBuffer;
    byte[] RByteArray = new byte[0]; // current received
    byte[] TmpByteArray = new byte[0]; // temporary array to be handled(concat, append)


    // Keep listening to the InputStream while connected
    while (true) {
        try {
            // Read from the InputStream
            bytes = mmInStream.read(buffer);
           
            if(bytes > 0) {  // 스트림으로부터 읽었을 경우 기존 못읽은 버퍼(TmpByteArray)에 append 시킴
              
                ByteBuffer ReceivedByteArrayBuffer = ByteBuffer.allocate(bytes); // received byte array
                RByteArray = ReceivedByteArrayBuffer.put(buffer,0,bytes).array();

                byte[] TmpBufferedArray = new byte[TmpByteArray.length + RByteArray.length];
                TmpByteArray = Conversion.appendArray(TmpByteArray, RByteArray); // 2바이트 -> integer 변환
            }

            if(TmpByteArray[0] != -1) // 헤더 파싱(헤더가 0xff입니다) 및 수신 누락된 경우에 대한 처리
            {
                int currentHeaderidx=0;
                for(int i=0; i<TmpByteArray.length;i++)
                {
                    if(TmpByteArray[i] == -1){
                        currentHeaderidx = i;
                        break;
                    }
                }

                ByteBuffer tmp = ByteBuffer.wrap(TmpByteArray,currentHeaderidx,TmpByteArray.length - currentHeaderidx - 1);
                TmpByteArray = tmp.array();
            }


            while(TmpByteArray.length >= 5)
            {
        // 2종류 데이터 파싱
                dat1 = Conversion.ByteArraytoInteger(TmpByteArray[1], TmpByteArray[2]);
                dat2 = Conversion.ByteArraytoInteger(TmpByteArray[3], TmpByteArray[4]);

        // 데이터 처리 코드 다수 포함됨...중략//   
 
        // 읽은 1패킷 잘라내는 부분...혹시 배열을 반복적으로 생성해서 오버헤드가 걸리는지...?
                byte[] reducedArray = new byte[TmpByteArray.length - 5];
                System.arraycopy(TmpByteArray,5,reducedArray,0,reducedArray.length);
                TmpByteArray = reducedArray;
            }

        } catch (IOException e) {
           
        }


    }

}
 
음...간단히 하려고 추리다보니 안보이는 변수도 있겠지만 스레드 내에 다 선언은 된 것들입니다.
말로 간단히 설명하자면
1. InputStream을 통해 읽기 시도하고, 읽은 byte 수가 있을경우 
2. (기존 처리되지 않은 byte 배열 + 현재 받은 byte 배열 ) 생성
3. 패킷단위로 데이터처리(5 byte) 및 해당 패킷 잘라냄(반복)
4. 다시 1로
이정도일것 같은데요, 말도안되게 느린것 같아서 효율적인 방법 알고계시면 알려주시면 감사하겠습니다~
GaKims (210 포인트) 님이 2016년 9월 28일 질문

1개의 답변

0 추천
아... 자답입니다.

문자열처리 코드가 같이돌아가고 있었네요. 여긴 없지만 삭제했더니 잘 됩니다...
GaKims (210 포인트) 님이 2016년 9월 28일 답변
...