Многопоточность с использованием сокетов - PullRequest
0 голосов
/ 10 ноября 2018

Я занимаюсь разработкой приложения, которое предназначено для измерения веса в промышленных масштабах: один, два или более.Вес каждой шкалы отправляется через интерфейс RS232 непрерывно (каждые 100 миллисекунд я получаю вес от шкалы, это означает, что время простоя низкое. Как только я начинаю получать вес от весов, которых он нене останавливайтесь) с помощью адаптера WiFi Serial.Я использую сокет соединения TCP, и он работает нормально, если я пытаюсь получить вес по одной шкале за раз.Я пытаюсь достичь следующего: я хочу слушать две или четыре весы одновременно и обновлять интерфейс в режиме реального времени, когда я получаю вес от весов.(Если я читаю весовую шкалу в один момент времени, она работает нормально).Я пробовал многопоточность, ThreadPoolExecutor, ThreadHandlers и т. Д., Но получил несколько ошибок (уверен, что я их не реализовал правильно, я новичок в многопоточности).Это код на данный момент:

Класс соединения получает вес от весов.Я передаю вес, полученный через интерфейс, другим классам

public class Connection implements Runnable {
public static final String LOG_TAG = Connection.class.getSimpleName();
public interface ConnectionDefinition {
    public ConnectionReader createReader(int timeout) throws IOException;

    public String getNameOrAddress();
}

public interface Listener {
    public void onException(Exception e);

    public void postWeight(double weight, boolean steady);
}

private ConnectionReader m_Reader;
private Listener m_Listener = s_NullListener;
private final ConnectionDefinition m_ConnectionDefinition;

private volatile boolean m_Continue = false;

private static final int s_Timeout = 5000;

public Connection(final ConnectionDefinition connectionDef) {
    m_ConnectionDefinition = connectionDef;
    start();
}

@Override
public void run() {
    m_Continue = true;
    while (m_Continue) {
        try {
            m_Reader = m_ConnectionDefinition.createReader(s_Timeout);
            final Result result = new Result();

            while (m_Continue) {
                m_Reader.read(result);

                final double weight = result.weight;
                final boolean steady = result.steady;

                Log.e(LOG_TAG, "Connection!!! " + String.valueOf(weight));

                m_Listener.postWeight(weight, steady);
            }
        } catch (final IOException e) {
            handleException(e);
        } finally {
            if (m_Reader != null)
                try {
                    m_Reader.close();
                } catch (final IOException ignored) {
                    // ignored
                }
            m_Reader = null;
        }
    }
}

private void handleException(final Exception e) {
    if (m_Continue) {
        m_Listener.onException(e);
        try {
            Thread.sleep(s_Timeout);
        } catch (final InterruptedException e1) {
        }
    }
}

public void start() {
    if (running())
        throw new IllegalStateException("Connection already running");

    final String name = m_ConnectionDefinition.getNameOrAddress();
    //Log.e(LOG_TAG, "Estoy en START! ");
    new Thread(this, "Scale Connection: " + name).start();
}

public void stop() {
    m_Continue = false;
    if (m_Reader != null) {
        try {
            m_Reader.stop();
        } catch (final IOException e) {
        }
    }
    //Log.e(LOG_TAG, "Estoy en STOP! ");
}

public boolean running() {
    return m_Continue;
}

public void setListener(final Listener listener) {
    if (listener != null)
        m_Listener = listener;
    else
        m_Listener = s_NullListener;
}

public void removeListener() {
    m_Listener = s_NullListener;
}

public ConnectionDefinition connectionDefinition() {
    return m_ConnectionDefinition;
}

private static Listener s_NullListener = new Listener() {
    @Override
    public void onException(final Exception e) {
    }

    @Override
    public void postWeight(final double weight, final boolean steady) {
    }
};

}

Я создал метод, в котором я пытаюсь прослушать различные меры веса и обновить пользовательский интерфейс (этот метод работает с одним слушателем одновременноОн корректно обновляет пользовательский интерфейс):

    private void connectionListener(){

        /*I GET THE CONNECTIONS DEFINED*/

        final List<ConnectionDefinition> connectionDefinition = Persistor.getInstance().connectionDefinitions();
        final ConnectionDefinition conDef = connectionDefinition.get(0);

/*MY APPROACH IS TO CREATE RUNNABLES TO PUT THE TO WORK IN DIFFERENT THREATS. UNTIL NOW IT DIDNT WORK*/

runnable1 = (new Runnable() {
            final Connection connection1 = new Connection(conDef);
            @Override
            public void run() {
                if(!connection1.running()) connection1.start();
                connection1.setListener(new Connection.Listener() {
                    @Override
                    public void postWeight(final double weight, final boolean steady) {
                        mHandler1.post(new Runnable() {
                            public void run() {
                                if(!Double.isNaN(weight)){
                                    Log.e(LOG_TAG, "Runnable 1 !!!");
                                    inputPesoRuedaDelanteraIzquierda.setText(String.valueOf(weight));
                                    //connection1.stop();
                                }
                            }
                        });
                    }
                    @Override
                    public void onException(final Exception e) {
                        e.printStackTrace();
                        //showMessage("Reintentando en 5 segs...");
                    }
                });
                /*
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }*/
            }
        });

        runnable2 = (new Runnable() {
            final Connection connection2 = new Connection(conDef);
            @Override
            public void run() {
                if(!connection2.running()) connection2.start();
                connection2.setListener(new Connection.Listener() {
                    @Override
                    public void postWeight(final double weight, final boolean steady) {
                        mHandler1.post(new Runnable() {
                            public void run() {
                                if(!Double.isNaN(weight)){
                                    Log.e(LOG_TAG, "Runnable 2 !!!");
                                    inputPesoRuedaDelanteraDerecha.setText(String.valueOf(weight));
                                    //connection2.stop();
                                }
                            }
                        });
                    }

                    @Override
                    public void onException(final Exception e) {
                        e.printStackTrace();
                        //showMessage("Reintentando en 5 segs...");
                    }
                });
                /*
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }*/
            }
        });

        worker = new WorkerThreadPool();
        worker.execute(runnable1);
        worker.execute(runnable2);

        /*
        Executor executor = new ThreadPerTaskExecutor();
        executor.execute(runnable1);
        executor.execute(runnable2);
        */
        //new Thread(runnable1).start();
        //new Thread(runnable2).start();


    }

Как видите, я пробовал разные подходы.Мне нужна помощь для реализации правильной, я открыт для других идей (может быть, итераторы слушателя, хотя мне нравится идея многопоточности)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...