编写用于发送和接收 UDP 数据包的服务 android

Writing a service for Sending and Receiving UDP Packets android

我正在开发一个在本地网络中发送和接收数据的应用程序。我决定编写一个服务来侦听传入的 UDP 数据包,当从其他设备接收到数据包时,该服务通过回调向 activity 报告传入消息,以更新 view.and 来自 [=27] =] 我在服务上调用一个方法将其发送到所需的目的地。 首先我想知道我的方法逻辑是否正确并且我为此选择了正确的工具(服务)。 而且服务上的监听方法也有问题,这是代码。它给出了 接收方法 :

的错误
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);
}

这是 activity 的 部分:

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);
}

好吧,你应该说出你收到的是哪个错误,但我猜这是一个 NetworkOnMainThreadException。

首先,您调用这个:

btnRec.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mService.Listen_Report();

    }
});

来自主线程。 即使您使用 BroadcastMessages 与服务通信(正如 Ata 告诉您的那样),主线程上的服务 运行,所以您也会遇到同样的问题。

您必须 运行 在另一个线程中使用接收方法,就像您使用发送方法一样。

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);
        }
    }

}