我在我的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)
無法確定,因爲您沒有發佈所有代碼,但我敢打賭,問題在於writeQueue的生產者/消費者問題 - 最後一個元素在isEmpty調用和get調用之間被刪除。你真的應該使用某種鎖定來防止它成爲問題。計數信號量在這裏是完美的,如果沒有數據可用,它也可以讓你不用等待。 –
@Gabe我現在已經發布了函數'sendPacket()'和'queueMessageForSending()'的代碼,這些函數在runnable中被調用。 –
哪一行是UdpSendService.java:119 – Henry