2013-01-21 21 views
0

我在我的android應用程序中有一個IntentService類,它將UDP數據包發送到服務器。在我之前的實現中,我沒有使用處理程序,代碼工作正常。我想在發送之前實現數據包的排隊。所以我創建了兩個分別用於寫入和讀取隊列的runnable。並嘗試使用處理程序執行它們。但是runnables不會被執行,並且拋出一個NullPointerExecption。我認爲執行處理程序時出現問題。我想知道使用處理程序執行runnables的正確方法。提前致謝。我已經發布了一些代碼段的logcat如下:Runnables不被Handler在android中執行

wHandler = new Handler(); 
rHandler = new Handler(); 
writer = new Runnable(){ 
    public void run(){ 
      switch (pType) { 
      case 0: 
       while (send) { 
        queueMessageForSending(msg.getBytes()); 
       } 
      case 1: 
       // Float f = new Float(delayField.getString()); 
       // for(int i=0;i<2000;i++) 
       while (send) { 
        try { 
         Thread.currentThread().sleep(delay); 
        } catch (Exception e) { 
        } 
        if(send) 
         queueMessageForSending(msg.getBytes()); 
       } 
       // break; 
      case 2: 
       // for(int i=0;i<10000;i++) 
       while (send) { 
        int u = want(30); 
        // int e=(int)Math.floor(-1*log(u)/(log((float)2.718)*2)); 
        // System.out.println(e); 
        String data1 = ""; 
        while ((u--) > 0) 
         data1 = data1 + msg; 
        if(send) 
         queueMessageForSending(data1.getBytes()); 
       } 
       // break; 
      case 3: 
       //float f2 = Float.parseFloat(delayField.getText().toString()); 
       // for(int i=0;i<50;i++) 
       while (send) { 
        int u = want(30); 
        // int e=(int)Math.floor(-1*log(u)/(log((float)2.718)*2)); 
        System.out.println(u); 
        String data1 = ""; 
        while ((u--) > 0) 
         data1 = data1 + msg; 
        System.out.println("data length :" + data1.length()); 
        try { 
         Thread.currentThread().sleep(delay); 
        } catch (Exception e) { 
        } 
        if(send) 
         queueMessageForSending(data1.getBytes()); 
       } 

      } 
      wHandler.post(this); 
     } 
    }; 
    reader = new Runnable(){ 
     public void run(){ 
      while(send){ 
       if (!writeQueue.isEmpty()) 
       { 
        byte[] sendData = (byte[]) writeQueue.elementAt(0); 
        sendPacket(sendData); 
       } 
      } 
      rHandler.post(this); 
     } 
    }; 

wHandler.post(writer); 
rHandler.post(reader); 

void sendPacket(byte[] data) { 
    //if(socket!=null){ 
    try { 
     System.out.println("\nClient:: Sending packet: " + " to " + addr 
       + port); 
     if(seq==100000) 
     { 
     seq=0; 
     } 
     Date d = new Date(); 
     Calendar c = Calendar.getInstance(); 
     c.setTime(d); 
     String time = c.get(Calendar.HOUR_OF_DAY) + ":" + 
     c.get(Calendar.MINUTE) + ":" + 
     c.get(Calendar.SECOND); 
    //System.out.println(time); 
     long sentTime = c.getTime().getTime(); 
     //System.out.println(sentTime+" "+seq); 
     header=" "+seq+" "+sendData.length+" "+sentTime+" "+time+" "; 
     seq++; 

     String s1= new String(sendData); 
     String s2= header+s1; 
     // System.out.println(s2); 
     byte[] sendDataFinal = (byte[]) s2.getBytes(); 
     spacket = new DatagramPacket(sendDataFinal, sendDataFinal.length, addr, port); 
     socket.send(spacket); 
     writeQueue.remove(data); 
     String resultTxt="Sent Packet at:"+DateFormat.format("MM/dd/yy h:mmaa", System.currentTimeMillis()); 
     broadcastIntent1.putExtra(PARAM_OUT_MSG, resultTxt); 
     sendBroadcast(broadcastIntent1); 
    } catch (Exception e) { 
     System.out.println("Error:" + e.getMessage()); 
     e.printStackTrace(); 
     return; 
    } 
} 

void queueMessageForSending(byte[] data) 
{ 
    if (data.length > DEFAULT_DATAGRAM_SIZE) 
    { 
    throw new IllegalArgumentException(
    "Message too long: limit is " + 
    DEFAULT_DATAGRAM_SIZE + " bytes"); 
    } 
    synchronized(writeQueue) 
    { 
    writeQueue.addElement(data); 
    writeQueue.notify(); 
    } 
} 

的logcat:

01-21 09:46:59.022: E/AndroidRuntime(915): FATAL EXCEPTION: IntentService[UdpService] 
01-21 09:46:59.022: E/AndroidRuntime(915): java.lang.NullPointerException 
01-21 09:46:59.022: E/AndroidRuntime(915): at com.example.udpmessageclient.UdpSendService$1.run(UdpSendService.java:119) 
01-21 09:46:59.022: E/AndroidRuntime(915): at android.os.Handler.handleCallback(Handler.java:615) 
01-21 09:46:59.022: E/AndroidRuntime(915): at android.os.Handler.dispatchMessage(Handler.java:92) 
01-21 09:46:59.022: E/AndroidRuntime(915): at android.os.Looper.loop(Looper.java:137) 
01-21 09:46:59.022: E/AndroidRuntime(915): at android.os.HandlerThread.run(HandlerThread.java:60) 
+0

無法確定,因爲您沒有發佈所有代碼,但我敢打賭,問題在於writeQueue的生產者/消費者問題 - 最後一個元素在isEmpty調用和get調用之間被刪除。你真的應該使用某種鎖定來防止它成爲問題。計數信號量在這裏是完美的,如果沒有數據可用,它也可以讓你不用等待。 –

+0

@Gabe我現在已經發布了函數'sendPacket()'和'queueMessageForSending()'的代碼,這些函數在runnable中被調用。 –

+0

哪一行是UdpSendService.java:119 – Henry

回答

0

Thread這樣啓動這些runnables

Thread t =new Thread(new Runnable() { 

     public void run() { 
      // do whatever you want to do inside runnable 

      // after functionality inside runnable is complete...call handler 
      Message msg= new Message(); 
      msg.what=1; 
      h.sendMessage(msg); 
     } 
}); 

後,你可以在裏面做所需的功能handler

Handler h =new Handler(){ 
     public void handleMessage(android.os.Message msg) 
     { 
      // do whatever you want to do in handler    
     } 
    }; 
+0

感謝您的答案。我應該在線程上調用'start()'方法嗎?哪裏應該聲明'runnables'? –

+0

yes ...應該在線程上調用start()方法。另外你可以在線程構造函數中聲明runnables。檢查以查看我的更新答案。 –

+0

@PoonamAnthony是否有效? –