2014-10-29 33 views
0

我建立在服務運行的是Android應用程序,它具有監聽TCP連接和接收消息和back.Actually我想要做的是響應線程給用戶選擇用yes或no迴應,當線程將接受連接,我的服務類是這樣的:改變變量的值在線程,而其運行

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我想要的線程等待消息直到線程該變量的值不changed.There是從哪兒我想改變這種variable.For現在正在調用sleep睡覺這個線程幾秒鐘,但其不正確的做法,因爲如果後幾秒鐘,用戶不要其他類不對spond它會自動發送null..please幫助下,我怎麼能做到這一點..

+0

接收消息 - >存儲連接 - >將消息傳播到用戶 - >檢索用戶響應 - >獲取存儲的連接 - >發送響應。 – Cativail 2014-10-29 11:00:41

回答

0

你可以把等待動作到一個循環,如果該值設置打破。 爲了能見度的原因,你應該使用一個volatile修飾符。

我會在一分鐘後一個例子。

volatile String valueIAmWaitingFor; // Class Variable 
... 

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

另一種方法現在可以設置valueIAmWaitingFor。

揮發性:

聲明揮發性Java變量的意思是:這個變量 的值將不會被線程本地緩存:所有讀取和寫入會 直奔「主存」;訪問該變量的行爲就好像它被包含在一個同步塊中,同步於自身。

這只是一個做到這一點的方式。還有更多的安全解決方案(也比這個修補程序更爲複雜)

編輯:當然它必須是valueIAmWaitingFor == null,而不是valueIAmWaitingFor != null

+0

它沒有工作:/ ... – Yasir 2014-10-29 10:52:38

+0

其仍然發送空,我不知道Y, – Yasir 2014-10-29 10:53:04

+0

其中/你是如何設置outgoingMsg? – huidube 2014-10-29 10:56:25