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

메인스레드에서 네트워크 사용못하는거 관련 질문입니다

0 추천

안드로이드 최근버전부터는 메인 UI스레드에서 네트워크 사용같은것을 하면 안되는것으로 알고있습니다.

그래서 소켓 통신을 하는 Thread를 만들었습니다.

 
 

public class MainActivity extends Activity {
 public final static int TECH_INFO    = 0X65;
 public final static int TECH_STAND = 0;
 public final static int TECH_TABLE = 1;
 public final static int TECH_PORTABLE = 2;
 

 SocketTest socketTest;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  final ToggleButton tb2 = (ToggleButton)findViewById(R.id.toggleButton1);
  final byte[] a = new byte [1];
  a[0] = (byte) TECH_STAND;
  
  final byte[] b = new byte [1];
  b[0] = (byte) TECH_TABLE;
  
  socketTest = new SocketTest();
  socketTest.start();
  
  tb2.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub
    if(tb2.isChecked()){
                    socketTest.sendCommandData(TECH_INFO, a);
                }else{
                 socketTest.sendCommandData(TECH_INFO, b);
                } // end if
   }
        });

 }



 

MainActivity 코드입니다. 이렇게 호출하는것도 메인스레드에서 네트워크를 사용하는셈인건가요? 그러면 어떻게 사용해야하나요??

 

아래는 소켓스레드 코드입니다.

 

public class SocketTest extends Thread{
 private int _timerCount = 0;
 private boolean _connect = false;
 
 private TimerTask _reconnectTimer;
 public final static int TECH_INFO    = 0X65;
 private static final int BUFFER_LEN = 1024;
 private static final int COMMAND_LEN = 1;
 
 
 public final static int TECH_STAND = 0;
 public final static int TECH_TABLE = 1;
 public final static int TECH_PORTABLE = 2;
 
 
 public ServerSocket serverSocket;
 public Socket socket = null;
 private int port = 9123;
 
 public void run()
 {
  try {
   Log.d("msg", "socket thread start");
   serverSocket = new ServerSocket(port);
   while(true) {
    socket = serverSocket.accept();
    
    if(_connect == false)
     NotifyConnect();
    
    try {
     BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
     byte[] buffer = new byte[BUFFER_LEN];
     while (socket.isConnected()) {
      int bytesRead = bis.read(buffer, 0, BUFFER_LEN);
      if (bytesRead >= 0) {
       byte command = buffer[0];

        //LogUtil.i("StandElin  >>>> else ");
        byte[] content = null;
        int length = 0;
        if (bytesRead > COMMAND_LEN) {
         content = new byte[bytesRead - COMMAND_LEN];
         length = content.length;
         System.arraycopy(buffer, COMMAND_LEN, content, 0, length);
        }
        Log.d("msg", "commnad" +command + "content" + content + "length" + length);
        //processPacket(command, content, length);
       
      }
      else
      {
       throw new Exception("Read is -1");        
      }
     }
    } catch (Exception e) {

     NotifyDisconnect();
    }
    
   }
  } catch (Exception e) {
   
  }
   

 }
  
 public void NotifyConnect()
 {
  _connect = true;
  
  ReconnectTimerStart();
 }
 
 public void ReconnectTimerStart()
 {
  
  final byte[] a = new byte [1];
  a[0] = (byte) TECH_PORTABLE;
  
  final byte[] b = new byte [1];
  b[0] = (byte) TECH_TABLE;
  
  final byte[] c = new byte [1];
  c[0] = (byte) TECH_PORTABLE;
  
  _timerCount = 0;
  _reconnectTimer = new TimerTask()
  {
   @Override
   public void run() {
    // TODO Auto-generated method stub
    switch(_timerCount)
    {
    case 0:
     sendCommandData(TECH_INFO, a);
     break;
    case 5:
     sendCommandData(TECH_INFO, b);
     break;
    case 10:
     sendCommandData(TECH_INFO, c);
     break;
     
    }
    _timerCount++;
    if(_timerCount > 10)
    {
     //_reconnectTimer.cancel();
     _timerCount=0;
     //_timerCount = 0;
    }
   }
 
  };
  Timer timer = new Timer();
  timer.schedule(_reconnectTimer, 2000, 1000);
 }
 
 public void NotifyDisconnect()
 {
  
 }
 
 public byte[] sendCommandData(int command, byte[] data) {
  byte[] packet = new byte[data.length + COMMAND_LEN];
  packet[0] = (byte)command;
  System.arraycopy(data, 0, packet, 1, data.length);
  sendPacket(packet);
  return packet;
 }
 
 public void sendPacket(byte[] packet) {
  try {
   Log.d("msg", "socket send packet");
   if(socket == null || socket.isConnected() == false)
    return;     
   
   synchronized (this) {
    BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
    Log.d("msg", "socket send packet1");
    bos.write(packet, 0, packet.length);
    Log.d("msg", "socket send packet2");
    bos.flush();
    Log.d("msg", "socket send packet3");
   }
  } catch (Exception e) {   
   for (StackTraceElement element : e.getStackTrace()) {              

            }    
   NotifyDisconnect();
  }
 }
}


 

메인에서 소켓스레드의 send command data 함수를 사용하여 데이터를 전송하고 싶습니다.

데이터 읽는거는 테스트때문에 비워놨습니다.

기존 안드로이드 낮은버전에서는 송수신 잘 됐었는데 지금 안드로이드 버전 높은것을 사용하면서

끊어진후 다시 연결되고 그때 데이터 송수신이 되어서 해결하고자 올린 코드만 따로 프로젝트만들어서 테스트 중입니다.

답변해주시면 감사합니다.

lissom (240 포인트) 님이 2020년 4월 8일 질문

1개의 답변

0 추천

사용하시는 방법도 불가능한 아니긴 하지만

HandlerThread 로 Handler 용 Thread를 별도로 돌린 후 Handler 를 통해 이벤트를 전달 하고,

Handler 에서 통신을 수행하게 구성하시는게 깔끔할 겁니다.

 

아래 코드를 참조 해 보세요.

https://programmingfbf7290.tistory.com/entry/2-%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%ED%81%B4%EB%9D%BC%EC%9D%B4%EC%96%B8%ED%8A%B8%EC%84%9C%EB%B2%84-%EC%86%8C%EC%BC%93-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8-%EA%B5%AC%ED%98%84

익명사용자 님이 2020년 4월 8일 답변
...