2014-10-29 4 views
0

서비스가 실행중인 안드로이드 앱을 만들고 있는데 TCP 연결을 수신하고 메시지를 수신하고 응답하는 스레드가 있습니다. 실제로 원하는 작업은 다음과 같습니다. 사용자에게 스레드가 연결을 받아 들일 때, 예 또는 아니오로 응답 할 수있는 기회를주고, 내 서비스 클래스는이입니다실행 중에 스레드의 변수 값을 변경합니다.

public class Receiver extends Service { 
    static String TCP_RECEIVE = "soft.b.peopleassist"; 
    public static String ip; 
    DatagramSocket socket; 
    private WifiManager.WifiLock wifiLock=null; 
    private PowerManager.WakeLock wakeLock=null; 
volatile public static String outgoingMsg="null"; 
    @SuppressLint("DefaultLocale") 


    public String getIpAddr() { 
      WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); 
      WifiInfo wifiInfo = wifiManager.getConnectionInfo(); 
      int ip = wifiInfo.getIpAddress(); 

      String ipString = String.format(
      "%d.%d.%d.%d", 
      (ip & 0xff), 
      (ip >> 8 & 0xff), 
      (ip >> 16 & 0xff), 
      (ip >> 24 & 0xff)); 

      return ipString; 
     } 



    private void listenAndWaitAndThrowIntent(Integer port) throws Exception { 
     ServerSocket ss = null; 
     try { 
      ss = new ServerSocket(port); 
      //ss.setSoTimeout(10000); 
      //accept connections 
      Socket s = ss.accept(); 
      BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); 
      BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); 
      //receive a message 




      String incomingMsg = in.readLine() + System.getProperty("line.separator"); 
      JSONObject jsonObj = new JSONObject(); 

      try { 
        jsonObj = new JSONObject(incomingMsg); 
      } catch (JSONException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

      try { 
       String trans=(String) jsonObj.get("TranId"); 
       String ide=(String) jsonObj.get("Amount"); 
       String hashs=(String) jsonObj.get("Basket"); 
       incomingMsg=trans+","+ide+","+hashs; 
      } catch (JSONException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      Log.i("TcpServer", "received: " + incomingMsg); 


      //send a message 
     // String outgoingMsg = "goodbye from port " + port + System.getProperty("line.separator"); 
      // outgoingMsg = "ok"; 

      broadcastIntent(incomingMsg); 
      incomingMsg=null; 
       Thread.sleep(3000); 

      out.write(outgoingMsg); 
      out.flush(); 

      Log.i("TcpServer", "sent: " + outgoingMsg); 

      broadcastIntent(incomingMsg); 

      //SystemClock.sleep(5000); 
      s.close(); 
      outgoingMsg="null"; 
     } catch (InterruptedIOException e) { 
      //if timeout occurs 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      if (ss != null) { 
       try { 
        ss.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 











    private void broadcastIntent(String message) { 
    Intent intent = new Intent(Receiver.TCP_RECEIVE); 
     intent.putExtra("messages", message); 
     sendBroadcast(intent); 
    } 

    Thread UDPBroadcastThread; 

    void startListenForUDPBroadcast() { 
     UDPBroadcastThread = new Thread(new Runnable() { 
      public void run() { 
       try { 
       // InetAddress broadcastIP = InetAddress.getByName(ip); //172.16.238.42 //192.168.1.255 
        Integer port = 21111; 
        while (shouldRestartSocketListen) { 
         listenAndWaitAndThrowIntent(port); 
        } 
        //if (!shouldListenForUDPBroadcast) throw new ThreadDeath(); 
       } catch (Exception e) { 
        Log.i("UDP", "no longer listening for UDP broadcasts cause of error " + e.getMessage()); 
       } 
      } 
     }); 
     UDPBroadcastThread.start(); 
    } 

    private Boolean shouldRestartSocketListen=true; 

    void stopListen() { 
     shouldRestartSocketListen = false; 
     if(socket!=null) 
     socket.close(); 
    } 

    @Override 
    public void onCreate() { 
     Log.i("Service", "WiFi lOCK"); 

     WifiManager wm = (WifiManager) getSystemService(Context.WIFI_SERVICE); 
     wifiLock = wm.createWifiLock(WifiManager.WIFI_MODE_FULL , "MyWifiLock"); 
     wifiLock.acquire(); 

     PowerManager powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE); 
     wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Lock"); 
     wakeLock.acquire(); 
    }; 

    @Override 
    public void onDestroy() { 
     stopListen(); 
     wifiLock.release(); 
      wakeLock.release(); 

     Log.i("UDP", "Service stoped"); 
    } 


    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 

      shouldRestartSocketListen = true; 

     startListenForUDPBroadcast(); 
     Log.i("TCP", "Service started"); 
     return START_STICKY; 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

} 

outGoingMsg 실제로 내가 스레드가 대기하고 싶은 response.Now 인 메시지입니다 스레드에서이 변수의 값이 변경되지 않을 때까지.이 변수를 변경하고 싶은 곳의 다른 클래스가 있습니다. 몇 초 동안이 스레드를 잠자기 상태로 호출하고 있습니다. ~하지 마라. 그것을 자동으로 null .. suppase 도움을 보내겠다. ..

+0

하는 메시지 수신 -> 사용자에게 메시지를 전파 -> 연결을 저장 - > 사용자 응답 검색 -> 저장된 연결 가져 오기 -> 응답 보내기. – Cativail

답변

0

값이 설정되면 중단되는 루프에 대기 동작을 넣을 수 있습니다. 가시성을 이유로 휘발성 수정자를 사용해야합니다.

예를 1 분 안에 게시 할 예정입니다.

volatile String valueIAmWaitingFor; // Class Variable 
... 

while(valueIAmWaitingFor == null){ 
    Thread.sleep(3000); 
} 
//go on 

다른 방법으로 이제 값을 설정할 수 있습니다. 휘발성

: 휘발성 자바 변수를 선언

의미 :이 변수 의 값은 스레드 로컬로 캐시되지 않습니다 : 모든 읽기 및 직선에 "메인 메모리" 갈 것이다 기록; 변수에 대한 액세스는 이 동기화 된 블록으로 묶여있는 것처럼 동작합니다 (자체 동기화 됨).

이것은이를 수행하는 한 가지 방법 일뿐입니다. 이

EDIT (이 핫픽스보다 더 복잡하지만) 더 많은 보안 솔루션입니다 : 그것을 가지고 물론이 valueIAmWaitingFor == null 될이, 그리고 valueIAmWaitingFor != null

+0

작동하지 않았다 :/.. – Yasir

+0

여전히 null을 보내고 있습니다. y는 알지 못합니다. – Yasir

+0

/outgoingMsg는 어디에서 설정하고 있습니까? – huidube

관련 문제