Я занимаюсь разработкой приложения, которое предназначено для измерения веса в промышленных масштабах: один, два или более.Вес каждой шкалы отправляется через интерфейс 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();
}
Как видите, я пробовал разные подходы.Мне нужна помощь для реализации правильной, я открыт для других идей (может быть, итераторы слушателя, хотя мне нравится идея многопоточности)