我正在开发一个在本地网络中发送和接收数据的应用。我决定编写一个侦听传入UDP数据包的服务,当收到来自其他设备的数据包时,服务报告通过回调活动来回传传入消息以更新视图。从活动我调用服务上的方法将其发送到所需的目的地。 首先,我想知道,如果我的方法逻辑是正确的,我选择了正确的工具(服务)。 并且在服务上的监听方法存在问题,这是代码。它给出了接收方法的错误:
public class WifiService extends Service {
private final IBinder mBinder = new WifiBinder();
private WifiInterface serviceCallbacks;
public WifiService() {
}
public class WifiBinder extends Binder {
WifiService getService() {
// Return this instance of LocalService so clients can call public methods
return WifiService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public void setCallbacks(WifiInterface callbacks) {
serviceCallbacks = callbacks;
}
public String Listen_Report() {
String msg = "";
try {
while (true) {
byte[] IncommingBuffer = new byte[1000];
InetAddress localaddress = InetAddress.getByName("192.168.43.1");
DatagramSocket rsc = new DatagramSocket(8008, localaddress);
DatagramPacket dgp = new DatagramPacket(IncommingBuffer, IncommingBuffer.length);
rsc.receive(dgp);
msg = new String(dgp.getData(), 0, dgp.getLength());
serviceCallbacks.ReportBack(msg);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return msg;
}
public void Sendmsg(final InetAddress dst, final String msg) throws IOException {
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
byte[] message = msg.getBytes();
DatagramPacket packet = new DatagramPacket(message, message.length,
dst, 8008);
DatagramSocket dsocket = new DatagramSocket();
dsocket.send(packet);
dsocket.close();
}
catch (UnknownHostException e) {
Log.e("Error", e.getMessage());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
}
这是界面:
public interface WifiInterface {
void ReportBack(String msg);
}
这是活动的部分:
btnRec.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mService.Listen_Report();
}
});
btnSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
mService.Sendmsg(InetAddress.getByName("192.168.43.83"),"From Activity");
} catch (IOException e) {
e.printStackTrace();
}
}
});
public void onStart(){
super.onStart();
// Bind to LocalService
Intent intent = new Intent(this, WifiService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className,
IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
WifiService.WifiBinder binder = (WifiService.WifiBinder) service;
mService = binder.getService();
mBound = true;
mService.setCallbacks(mainMenu);
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
@Override
public void ReportBack(String msg) {
txtRec.setText(msg);
}
答案 0 :(得分:0)
好吧,你应该说你收到了哪个错误,但我认为它是一个NetworkOnMainThreadException。
首先,你称之为:
btnRec.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mService.Listen_Report();
}
});
来自主线程。 即使你使用BroadcastMessages与服务通信(如Ata告诉你的那样),服务也在主线程上运行,因此你会遇到同样的问题。
您必须在另一个线程中运行receive方法,就像使用send方法一样。
public void Receivemsg() throws IOException {
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
byte[] IncommingBuffer = new byte[1000];
InetAddress localaddress = InetAddress.getByName("192.168.43.1");
DatagramSocket rsc = new DatagramSocket(8008, localaddress);
DatagramPacket dgp = new DatagramPacket(IncommingBuffer, IncommingBuffer.length);
rsc.receive(dgp);
msg = new String(dgp.getData(), 0, dgp.getLength());
serviceCallbacks.ReportBack(msg);
}
}
}).start();
}
}
然后:
public void Listen_Report()
{
try
{
Receivemsg();
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
catch (SocketException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
最后(因为回调将在主线程之外调用)
@Override
public void ReportBack(String msg) {
runOnUiThread(new Runnable()
{
@Override
public void run()
{
txtRec.setText(msg);
}
}
}