Android 8.0(Oreo)突然停止了多播线程

时间:2018-11-24 07:33:26

标签: java android multithreading multicast

我有一些代码可以侦听Windows应用程序发送的多播,它在android 7.0及以下版本上运行正常,但在android 8.0上,则可以在5分钟到1小时内随机停止,而不会引发异常。我不确定这是否受Android 8.0中引入的Background Service Limitations影响。但我进行了一些研究,有人说它不应该受到影响,因为它是线程here!但是由于它仍然是后台线程,因此我不确定。

这是我的多播线程代码:

public class MulticastThread extends Thread {



final AtomicBoolean running = new AtomicBoolean(true);
final Activity mActivity;
final String multicastIP;
final int multicastPort;
final Handler handler;

protected MulticastSocket multicastSocket;
private InetAddress inetAddress;
private NetworkInterface networkInterface;

public MulticastThread(String threadName, Activity mActivity, String multicastIP, int multicastPort, Handler handler) {
    super(threadName);
    this.mActivity = mActivity;
    this.multicastIP = multicastIP;
    this.multicastPort = multicastPort;
    this.handler = handler;
}

@Override
public void run() {
    try {

        WifiManager wifiManager = (WifiManager) mActivity.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        int wifiIPInt = wifiInfo.getIpAddress();
        byte[] wifiIPByte = new byte[]{
                (byte) (wifiIPInt & 0xff),
                (byte) (wifiIPInt >> 8 & 0xff),
                (byte) (wifiIPInt >> 16 & 0xff),
                (byte) (wifiIPInt >> 24 & 0xff)};
        this.inetAddress = InetAddress.getByAddress(wifiIPByte);
        this.networkInterface = NetworkInterface.getByInetAddress(inetAddress);

        this.multicastSocket = new MulticastSocket(multicastPort);
        multicastSocket.setNetworkInterface(networkInterface);
        multicastSocket.joinGroup(InetAddress.getByName(multicastIP));
        multicastSocket.setSoTimeout(100);
        multicastSocket.setTimeToLive(2);
    } catch (BindException e) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if(mActivity instanceof CameraActivity){
                    ((CameraActivity) mActivity).stopListening();
                }
            }
        });
        String error = "Error: Cannot bind Address or Port.";
        if (multicastPort < 1024)
            error += "\nTry binding to a port larger than 1024.";
        outputErrorToConsole(error);
        Log.d("ETO>>>",e+"");
    } catch (IOException e) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if(mActivity instanceof CameraActivity){
                    ((CameraActivity) mActivity).stopListening();
                }
            }
        });
        String error = "Error: Cannot bind Address or Port.\n"
                + "An error occurred: " + e.getMessage();
        outputErrorToConsole(error);
        Log.d(">>>",e+"");
    }catch (Throwable e )
    {
        Log.d(">>>",e+"");
    }
}

String getLocalIP() {
    return this.inetAddress.getHostAddress();
}

void outputErrorToConsole(final String errorMessage) {
    handler.post(new Runnable() {
        @Override
        public void run() {
            if(mActivity instanceof CameraActivity){
                ((CameraActivity) mActivity).showError(errorMessage);
            }
        }
    });
}

public void stopRunning() {
    this.running.set(false);
}

}

以下是多播侦听器的代码:

public class MulticastListenerThread extends MulticastThread {

private DatagramPacket packet;
private long newSeqNum;
private long lastSeqNum;
AppSettings appSettings;

public MulticastListenerThread(Activity activity, String multicastIP, int multicastPort) {
    super("MulticastListenerThread", activity, multicastIP, multicastPort, new Handler());
}


@Override
public void run() {


    super.run();
    appSettings = AppSettings.getAppSettingsFromSharedPreference(mActivity);
    newSeqNum = 0;
    lastSeqNum = 0;



    this.packet = new DatagramPacket(new byte[65536], 65536);

    while (running.get()) {
        packet.setData(new byte[65536]);

        try {
            if (multicastSocket != null)
                multicastSocket.receive(packet);
            else
                break;
        } catch (IOException ignored) {
            continue;
        }

        final String data = new String(packet.getData()).trim();
        Log.i("Multicast", data);

        this.handler.post(new Runnable() {
            @Override
            public void run() {
                if (mActivity instanceof CameraActivity) {

                  //  ((CameraActivity) mActivity).log(consoleMessage);

                    String actionMessage = "";

                    long timer=0;

                    if (data.contains("seq")) {
                        if(data.contains(",")) {
                            String[] result = data.split(",");
                            String data2 = result[0];
                            timer = Long.parseLong(result[1]);
                            newSeqNum = Long.valueOf(data2.substring(data2.lastIndexOf("_") + 1));
                            String messageWithSubSeq = data2.substring(0, (data2.lastIndexOf("_seq_")));
                            actionMessage = messageWithSubSeq.substring(0, (messageWithSubSeq.lastIndexOf("_")));
                        }else {
                            // long l = Long.parseLong(str);
                            newSeqNum = Long.valueOf(data.substring(data.lastIndexOf("_") + 1));
                            String messageWithSubSeq = data.substring(0, (data.lastIndexOf("_seq_")));
                            actionMessage = messageWithSubSeq.substring(0, (messageWithSubSeq.lastIndexOf("_")));
                        }

                    }else if(data.contains("synctime"))
                    {

                        appSettings = AppSettings.getAppSettingsFromSharedPreference(mActivity);
                        appSettings.setCheckaudit(true);
                        appSettings.save(mActivity);
                        ((CameraActivity) mActivity).onSynctime();


                    }else if(data.contains("processtime"))
                    {
                        appSettings = AppSettings.getAppSettingsFromSharedPreference(mActivity);
                        appSettings.setUpload(false);
                        appSettings.save(mActivity);


                        ((CameraActivity) mActivity).onCancelUpload();
                    }




                    Log.d("Received! " , ""+data);
                }
            }
        });
    }
    if (multicastSocket != null)
        this.multicastSocket.close();
}

}

我使用以下函数在onResume的主要活动上对其进行初始化:

public void startListening() {

    appSettings = AppSettings.getAppSettingsFromSharedPreference(this);

    if (!isListening) {
        ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
        if (connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected()) {
            setWifiLockAcquired(true);

            this.multicastListenerThread = new MulticastListenerThread(this,  Constants.INET_ADDRESS,
                    Constants.MULTISOCKET_PORT);





            multicastListenerThread.start();

            Log.d(">>>>>",multicastListenerThread.getPriority()+"");

            isListening = true;

        } else {
            showError("Connect to  Network");
        }


   }
}

然后我用onDestroy停止线程:

private void stopThreads() {
    if (this.multicastListenerThread != null)
        this.multicastListenerThread.stopRunning();
    if (this.multicastSenderThread != null)
        this.multicastSenderThread.interrupt();


}

0 个答案:

没有答案