Помогите розобраться с потоком Handler

Ответить
Chvalov
Сообщения: 24
Зарегистрирован: 28 мар 2014, 16:57

Помогите розобраться с потоком Handler

Сообщение Chvalov » 28 авг 2015, 19:22

Не могу разобраться каким образом у меня работает Handler, насколько я понял то он только в потоке обрабатывает ответы от самого контролера.
Как мне в этот же Handler запихнуть еще одну задачу чтобы работало вечно с задержкой в 200 миллисекунд:

Вот мой код:
[syntax=java]package com.physicaloid.tutorial5;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.physicaloid.lib.Physicaloid;
import com.physicaloid.lib.usb.driver.uart.ReadLisener;
import com.physicaloid.lib.usb.driver.uart.UartConfig;

public class Tutorial5Activity extends Activity {
private static final String TAG = Tutorial5Activity.class.getSimpleName();
Button btOpen, btClose, btCommand_1, btCommand_2, btCommand_3;
TextView tvRead;
private byte[] bytesToSend;//масив байтов для отправки на контроллер

Physicaloid mPhysicaloid;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tutorial5);

btOpen = (Button) findViewById(R.id.btOpen);
btClose = (Button) findViewById(R.id.btClose);
btCommand_1 = (Button) findViewById(R.id.btCommand_1);
btCommand_2= (Button) findViewById(R.id.btCommand_2);
btCommand_3= (Button) findViewById(R.id.btCommand_3);
tvRead = (TextView) findViewById(R.id.tvRead);

setEnabledUi(false);

mPhysicaloid = new Physicaloid(this);

//****************************************************************
// TODO : register intent filtered actions for device being attached or detached
IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(mUsbReceiver, filter);
//****************************************************************
}

@Override
public void onDestroy() {
super.onDestroy();
//****************************************************************
// TODO : unregister the intent filtered actions
unregisterReceiver(mUsbReceiver);
//****************************************************************
}

public void onClickOpen(View v) {
openDevice();
}

private void openDevice() {
if (!mPhysicaloid.isOpened()) {
if (mPhysicaloid.open()) { // default 9600bps
setEnabledUi(true);

// Присваиваем подключеному устройству нужную конфигурацию
UartConfig uartConfig = new UartConfig(19200, UartConfig.DATA_BITS8, UartConfig.STOP_BITS1, UartConfig.PARITY_NONE, false, false);
mPhysicaloid.setConfig(uartConfig);

mPhysicaloid.addReadListener(new ReadLisener() {
String readStr;

// callback when reading one or more size buffer
@Override
public void onRead(int size) {
byte[] buf = new byte[size];

mPhysicaloid.read(buf, size);
try {
readStr = new String(buf, "UTF-8");
} catch (UnsupportedEncodingException e) {
Log.e(TAG, e.toString());
return;
}

// UI thread
tvAppend(tvRead, Arrays.toString(buf) + "\n"); // выводим масив байт (Ответ контролера)
}
});
}
}
}

public void onClickClose(View v) {
closeDevice();
}

private void closeDevice() {
if(mPhysicaloid.close()) {
setEnabledUi(false);
mPhysicaloid.clearReadListener();
}
}

// Статус - должен опрашиваться каждые 200 миллисекунд !
public void onClickSendOneCommands(View v) {
bytesToSend= new byte[]{1, 3, 0, 0, 0, 0, 0 ,0};
mPhysicaloid.write(bytesToSend, bytesToSend.length);
}

// Включить двигатель
public void onClickSendTwoCommands(View v) {
bytesToSend= new byte[]{1, 5, 1, 5, 0, 0, 0 ,0};
mPhysicaloid.write(bytesToSend, bytesToSend.length);
}

// Выключить двигатель
public void onClickSendThreeCommands(View v) {
bytesToSend= new byte[]{1, 5, 1, 1, 0, 0, 0 ,0};
mPhysicaloid.write(bytesToSend, bytesToSend.length);
}


Handler mHandler = new Handler();
private void tvAppend(TextView tv, CharSequence text) {
final TextView ftv = tv;
final CharSequence ftext = text;
mHandler.post(new Runnable() {
@Override
public void run() {
ftv.append(ftext);
}
});
}

// Активируем & деактивируем элементы в зависимости от того подключено ли устройство
private void setEnabledUi(boolean on) {
if(on) {
btOpen.setEnabled(false);
btClose.setEnabled(true);
btCommand_1.setEnabled(true);
btCommand_2.setEnabled(true);
btCommand_3.setEnabled(true);
tvRead.setEnabled(true);
} else {
btOpen.setEnabled(true);
btClose.setEnabled(false);
btCommand_1.setEnabled(false);
btCommand_2.setEnabled(false);
btCommand_3.setEnabled(false);
tvRead.setEnabled(false);
}
}

// Выполняем действие при подключении устройства
protected void onNewIntent(Intent intent) {
String action = intent.getAction();

if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
openDevice();
}
};

// Выполняет действие при отключении устройства
BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();

if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
closeDevice();
}
}
};
}[/syntax]

Вообщем нужно код который выполняется при нажатии кнопки COM 1(onClickSendOneCommands) убрать од-туда и сделать так чтобы он работал вечно отправляя команды с задержкой в 100 миллисекунд
[syntax=java] // Статус - должен опрашиваться каждые 200 миллисекунд !
public void onClickSendOneCommands(View v) {
bytesToSend= new byte[]{1, 3, 0, 0, 0, 0, 0 ,0};
mPhysicaloid.write(bytesToSend, bytesToSend.length);
}[/syntax]
П.С. Работать вечно он должен только когда есть подключен контролер то-есть код должен выполнятся в методе openDevice()
после строк:
[syntax=java] // Присваиваем подключеному устройству нужную конфигурацию
UartConfig uartConfig = new UartConfig(19200, UartConfig.DATA_BITS8, UartConfig.STOP_BITS1, UartConfig.PARITY_NONE, false, false);
mPhysicaloid.setConfig(uartConfig);[/syntax]

Для более лучшего понимания, прикрепил проект к теме !!!
Тому кто поможет закину пару рублей на пиво!
Вложения
ControllerTest.zip
Мой проект для более полного понимания кода.
(1.75 МБ) 188 скачиваний

Аватара пользователя
doter.ua
Сообщения: 1106
Зарегистрирован: 23 ноя 2013, 16:08
Откуда: Ukraine

Re: Помогите розобраться с потоком Handler

Сообщение doter.ua » 28 авг 2015, 21:55

Это делается за 5 мин с рекурсивными вызовами хендлера и булкой для выхода.
Если на пальцах:

Код: Выделить всё

public void myMethod()
   handler.postDelayed(new Runnable(){
            @Override
            public void run() {
                //todo
                if( глобальная_булка ){
                   myMethod();
                }
          }
    }, 200  );
}
Семь раз отмерь - поставь студию.
Эклипс не студия, ошибка вылетит - не исправишь.
Скажи мне кто твой друг, и оба поставили студию.
Студия - свет, а эклипс - тьма.

Ответить