我有一个服务运行,它在局域网中接收广播消息,我已经从片段启动了服务,我想在片段被销毁时停止服务,但是当我调用stopservice时它给NPE。 我的服务调用片段是:
public class Receive extends Fragment {
TextView tv1,tv2;
Intent intent;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView =inflater.inflate(R.layout.receive, container, false);
intent = new Intent(getActivity(), Server.class);
tv1=(TextView)rootView.findViewById(R.id.textView1);
tv2=(TextView)rootView.findViewById(R.id.textView2);
//getActivity().startService(intent);
return rootView;
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateUI(intent);
}};
private void updateUI(Intent intent) {
Toast.makeText(getActivity().getApplicationContext(), "Yea!!! Service called", Toast.LENGTH_SHORT).show();
String message = intent.getStringExtra("messages");
String senderip = intent.getStringExtra("sender");
tv2.setText(message);
tv1.setText(senderip);
}
@Override
public void onResume() {
super.onResume();
getActivity().startService(intent);
getActivity().registerReceiver(broadcastReceiver, new IntentFilter(
Server.UDP_BROADCAST));
Log.i("UDP", "reg started");
}
@Override
public void onPause() {
super.onPause();
getActivity(). unregisterReceiver(broadcastReceiver);
getActivity().stopService(intent);
Log.i("UDP", "unreg started");
}
}
我的服务是:
public class Server extends Service {
static String UDP_BROADCAST = "soft.b.peopleassist";
//Boolean shouldListenForUDPBroadcast = false;
DatagramSocket socket;
//Intent intent;
private void listenAndWaitAndThrowIntent(InetAddress broadcastIP, Integer port) throws Exception {
byte[] recvBuf = new byte[15000];
if (socket == null || socket.isClosed()) {
socket = new DatagramSocket(port, broadcastIP);
socket.setBroadcast(true);
}
//socket.setSoTimeout(1000);
DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
Log.e("UDP", "Waiting for UDP broadcast");
socket.receive(packet);
String senderIP = packet.getAddress().getHostAddress();
String message = new String(packet.getData());
Log.e("UDP", "Got UDB broadcast from " + senderIP + ", message: " + message);
broadcastIntent(senderIP, message);
socket.close();
}
private void broadcastIntent(String senderIP, String message) {
Intent intent = new Intent(Server.UDP_BROADCAST);
intent.putExtra("sender", senderIP);
intent.putExtra("messages", message);
sendBroadcast(intent);
}
Thread UDPBroadcastThread;
void startListenForUDPBroadcast() {
UDPBroadcastThread = new Thread(new Runnable() {
public void run() {
try {
InetAddress broadcastIP = InetAddress.getByName("192.168.1.255"); //172.16.238.42 //192.168.1.255
Integer port = 11111;
while (shouldRestartSocketListen) {
listenAndWaitAndThrowIntent(broadcastIP, 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;
socket.close();
}
@Override
public void onCreate() {
};
@Override
public void onDestroy() {
stopListen();
//stopService(intent);
Log.i("UDP", "Service stoped");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
shouldRestartSocketListen = true;
startListenForUDPBroadcast();
Log.i("UDP", "Service started");
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
我的logcat是:
09-03 09:17:21.995: D/gralloc_goldfish(908): Emulator without GPU emulation detected.
09-03 09:17:28.763: I/UDP(908): reg started
09-03 09:17:28.853: I/UDP(908): Service started
09-03 09:17:28.993: I/UDP(908): no longer listening for UDP broadcasts cause of error bind failed: EADDRNOTAVAIL (Cannot assign requested address)
09-03 09:17:30.653: I/UDP(908): unreg started
09-03 09:17:30.893: D/AndroidRuntime(908): Shutting down VM
09-03 09:17:30.893: W/dalvikvm(908): threadid=1: thread exiting with uncaught exception (group=0x409961f8)
09-03 09:17:30.963: E/AndroidRuntime(908): FATAL EXCEPTION: main
09-03 09:17:30.963: E/AndroidRuntime(908): java.lang.RuntimeException: Unable to stop service soft.b.peopleassist.Server@4137dbb8: java.lang.NullPointerException
09-03 09:17:30.963: E/AndroidRuntime(908): at android.app.ActivityThread.handleStopService(ActivityThread.java:2405)
09-03 09:17:30.963: E/AndroidRuntime(908): at android.app.ActivityThread.access$2000(ActivityThread.java:122)
09-03 09:17:30.963: E/AndroidRuntime(908): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1212)
09-03 09:17:30.963: E/AndroidRuntime(908): at android.os.Handler.dispatchMessage(Handler.java:99)
09-03 09:17:30.963: E/AndroidRuntime(908): at android.os.Looper.loop(Looper.java:137)
09-03 09:17:30.963: E/AndroidRuntime(908): at android.app.ActivityThread.main(ActivityThread.java:4340)
09-03 09:17:30.963: E/AndroidRuntime(908): at java.lang.reflect.Method.invokeNative(Native Method)
09-03 09:17:30.963: E/AndroidRuntime(908): at java.lang.reflect.Method.invoke(Method.java:511)
09-03 09:17:30.963: E/AndroidRuntime(908): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
09-03 09:17:30.963: E/AndroidRuntime(908): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
09-03 09:17:30.963: E/AndroidRuntime(908): at dalvik.system.NativeStart.main(Native Method)
09-03 09:17:30.963: E/AndroidRuntime(908): Caused by: java.lang.NullPointerException
09-03 09:17:30.963: E/AndroidRuntime(908): at soft.b.peopleassist.Server.stopListen(Server.java:68)
09-03 09:17:30.963: E/AndroidRuntime(908): at soft.b.peopleassist.Server.onDestroy(Server.java:78)
09-03 09:17:30.963: E/AndroidRuntime(908): at android.app.ActivityThread.handleStopService(ActivityThread.java:2388)
09-03 09:17:30.963: E/AndroidRuntime(908): ... 10 more
09-03 09:17:33.533: I/Process(908): Sending signal. PID: 908 SIG: 9
先谢谢。
答案 0 :(得分:0)
在stopListen()
方法中设置stop boolean,然后立即关闭套接字。
有可能,你的另一个线程正在深入研究它。我建议你在他们创建的线程中关闭套接字。例如catchblock中的socket.close()
并将其从stopListen()
中删除。