Каков самый простой способ обновить TextView из службы?

Я делаю приложение, которое состоит из действия и службы. При нажатии кнопки служба запускается, она собирает данные с датчика в фоновом режиме, классифицирует их и выводит строку. Я хочу отобразить строку в textView. Прямо сейчас я вижу в журнале, что переменная обновляется 2 раза в секунду, но когда я пытаюсь обновить textView из класса обслуживания, ничего не происходит, если я не нажимаю кнопку, всякий раз, когда я нажимаю кнопку, строка отображается в textView.

Какое здесь самое простое решение? Я попытался сделать textView статическим, но он все еще не может его обновить. Можно ли сделать так, чтобы представление обновлялось автоматически каждую секунду? Могу я как-нибудь добавить слушателя? Поскольку я не очень опытен, мне нужно простое решение, которое не обязательно должно быть «хорошим».

Вот мой код

Деятельность:

public class CollectorActivity extends Activity {

private enum State {
    IDLE, COLLECTING, TRAINING, CLASSIFYING
};

private final String[] mLabels = { Globals.CLASS_LABEL_STANDING,
        Globals.CLASS_LABEL_WALKING, Globals.CLASS_LABEL_RUNNING,
        Globals.CLASS_LABEL_OTHER };

private RadioGroup radioGroup;
private final RadioButton[] radioBtns = new RadioButton[4];
private Intent mServiceIntent;
private File mFeatureFile;
public static TextView mCurrentLabel;

private State mState;
private Button btnDelete;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    radioGroup = (RadioGroup) findViewById(R.id.radioGroupLabels);
    radioBtns[0] = (RadioButton) findViewById(R.id.radioStanding);
    radioBtns[1] = (RadioButton) findViewById(R.id.radioWalking);
    radioBtns[2] = (RadioButton) findViewById(R.id.radioRunning);
    radioBtns[3] = (RadioButton) findViewById(R.id.radioOther);

    btnDelete = (Button) findViewById(R.id.btnDeleteData);
    mCurrentLabel = (TextView) findViewById(R.id.textView);

    mState = State.IDLE;
    mFeatureFile = new File(getExternalFilesDir(null),
            Globals.FEATURE_FILE_NAME);
    mServiceIntent = new Intent(this, SensorsService.class);


}



public void onCollectClicked(View view) {

    if (mState == State.IDLE) {
        mState = State.COLLECTING;
        ((Button) view).setText(R.string.ui_collector_button_stop_title);
        btnDelete.setEnabled(false);
        radioBtns[0].setEnabled(false);
        radioBtns[1].setEnabled(false);
        radioBtns[2].setEnabled(false);
        radioBtns[3].setEnabled(false);

        int acvitivtyId = radioGroup.indexOfChild(findViewById(radioGroup
                .getCheckedRadioButtonId()));
        String label = mLabels[acvitivtyId];

        Bundle extras = new Bundle();
        extras.putString(Globals.CLASS_LABEL_KEY, label);
        mServiceIntent.putExtras(extras);

        startService(mServiceIntent);

    } else if (mState == State.COLLECTING) {
        mState = State.IDLE;
        ((Button) view).setText(R.string.ui_collector_button_start_title);
        btnDelete.setEnabled(true);
        radioBtns[0].setEnabled(true);
        radioBtns[1].setEnabled(true);
        radioBtns[2].setEnabled(true);
        radioBtns[3].setEnabled(true);

        stopService(mServiceIntent);
        ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).cancelAll();
    }
}

public void onDeleteDataClicked(View view) {

    if (Environment.MEDIA_MOUNTED.equals(Environment
            .getExternalStorageState())) {
        if (mFeatureFile.exists()) {
            mFeatureFile.delete();
        }

        Toast.makeText(getApplicationContext(),
                R.string.ui_collector_toast_file_deleted,
                Toast.LENGTH_SHORT).show();
    }
}

@Override
public void onBackPressed() {

    if (mState == State.TRAINING) {
        return;
    } else if (mState == State.COLLECTING || mState == State.CLASSIFYING) {
        stopService(mServiceIntent);
        ((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
                .cancel(Globals.NOTIFICATION_ID);
    }
    super.onBackPressed();
}

@Override
public void onDestroy() {
    // Stop the service and the notification.
    // Need to check whether the mSensorService is null or not.
    if (mState == State.TRAINING) {
        return;
    } else if (mState == State.COLLECTING || mState == State.CLASSIFYING) {
        stopService(mServiceIntent);
        ((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
                .cancelAll();
    }
    finish();
    super.onDestroy();
}

А это метод doInBackground в моем классе обслуживания. Строка «CollectorActivity.mCurrentLabel.setText (классификация);» это проблема. Я хочу, чтобы это постоянно обновляло textView.

 public class OnSensorChangedTask extends AsyncTask<Void, Void, Void> {
    @Override
    protected Void doInBackground(Void... arg0) {



        Instance inst = new DenseInstance(mFeatLen);
        inst.setDataset(mDataset);
        Instance inst2 = new DenseInstance(65);
        int blockSize = 0;
        FFT fft = new FFT(Globals.ACCELEROMETER_BLOCK_CAPACITY);
        double[] accBlock = new double[Globals.ACCELEROMETER_BLOCK_CAPACITY];
        double[] re = accBlock;
        double[] im = new double[Globals.ACCELEROMETER_BLOCK_CAPACITY];

        double max = Double.MIN_VALUE;

        while (true) {
            try {
                // need to check if the AsyncTask is cancelled or not in the while loop
                if (isCancelled () == true)
                {
                    return null;
                }

                // Dumping buffer
                accBlock[blockSize++] = mAccBuffer.take().doubleValue();


                if (blockSize == Globals.ACCELEROMETER_BLOCK_CAPACITY) {
                    blockSize = 0;
                    testList = new ArrayList<Double>();

                    // time = System.currentTimeMillis();
                    max = .0;
                    for (double val : accBlock) {
                        if (max < val) {
                            max = val;
                        }
                    }

                    fft.fft(re, im);

                    for (int i = 0; i < re.length; i++) {
                        double mag = Math.sqrt(re[i] * re[i] + im[i]
                                * im[i]);
                        inst.setValue(i, mag);
                        testList.add(i,mag);
                        im[i] = .0; // Clear the field
                    }

                    // Append max after frequency component
                    inst.setValue(Globals.ACCELEROMETER_BLOCK_CAPACITY, max);
                    inst2.setValue(Globals.ACCELEROMETER_BLOCK_CAPACITY, max);
                    testList.add(max);


                     classificationIndex = WekaClassifier.classify(testList.toArray());
                     classification = testLabel.get((int) classificationIndex);
                     CollectorActivity.mCurrentLabel.setText(classification);

                    inst.setValue(mClassAttribute, mLabel);
                    mDataset.add(inst);
                    Log.i("new instance", mDataset.size() + "");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
29
1

Ответы 1

В doInBackground(Void... arg0) измените CollectorActivity.mCurrentLabel.setText(classification); на publishProgress(classification);, затем измените второй аргумент с Void на String: public class OnSensorChangedTask extends AsyncTask<Void, Srting, Void> и добавьте onProgressUpdate().

Наконец, ваш код должен выглядеть так:

public class OnSensorChangedTask extends AsyncTask<Void, Srting, Void> {

@Override
protected Void doInBackground(Void... arg0) {
    //...
    publishProgress(classification);
    //...
}

@Override
protected Void onProgressUpdate(String... classification) {
     CollectorActivity.mCurrentLabel.setText(classification[0]);
}

Другие вопросы по теме