2014-10-29 59 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