Cassey
Cassey

Reputation: 1

Android Studio error: "Method getText must be called from the UI Thread, currently inferred thread is worker

I got a problem about gettext(), Android studio says that 'method getText must be called from the UI Thread,currently inferred thread is worker'. Can someone help me with this or can someone give an idea how to fix this? Thanks!

package com.ibm.watsonvoicetts;

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.ibm.watson.developer_cloud.android.library.audio.StreamPlayer;
import com.ibm.watson.developer_cloud.text_to_speech.v1.TextToSpeech;
import com.ibm.watson.developer_cloud.text_to_speech.v1.model.Voice;

public class MainActivity extends AppCompatActivity {

TextView textView;
EditText editText;
Button button;

StreamPlayer streamPlayer;


private TextToSpeech initTextToSpeechService(){
    TextToSpeech service = new TextToSpeech();
    String username = "";
    String password = "";
    service.setUsernameAndPassword(username, password);
    return service;
}

private class WatsonTask extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... textToSpeak) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                textView.setText("running the Watson thread");
            }
        });

        TextToSpeech textToSpeech = initTextToSpeechService();
        streamPlayer = new StreamPlayer();
        streamPlayer.playStream(textToSpeech.synthesize(
                String.valueOf(editText.getText()),【**here is the problem**】
                Voice.EN_MICHAEL).execute());

        return "text to speech done";
    }

    @Override
    protected void onPostExecute(String result) {
        textView.setText("TTS status: " + result);
    }

}

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

    editText = (EditText) findViewById(R.id.editText);
    button = (Button) findViewById(R.id.button);
    textView = (TextView) findViewById(R.id.textView);

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            System.out.println("the text to speech: " + editText.getText());
            textView.setText("TTS: " + editText.getText());

            WatsonTask task = new WatsonTask();
            task.execute(new String[]{});


        }
    });
}

}

Upvotes: 0

Views: 874

Answers (2)

Avijit Karmakar
Avijit Karmakar

Reputation: 9398

doInBackground() method runs on different thread not in UI thread.

streamPlayer.playStream(textToSpeech.synthesize(
                String.valueOf(editText.getText()),【**here is the problem**】
                Voice.EN_MICHAEL).execute());

You are calling getText() method of edittext in this doInBackground() method. That's why it's giving error. Any work of view related things, we have to do it in UI thread.

One thing you can do it, you can place this code within runOnUiThread.

Upvotes: 0

Samuel
Samuel

Reputation: 17171

You shouldn't call getText from an AsyncTask like you're doing. The solution is to pass the value into the task's constructor.

Change

WatsonTask task = new WatsonTask(editText.getText());

and

private class WatsonTask extends AsyncTask<String, Void, String> {
    private final String text;
    public WatsonTask(String text) {
        super();
        this.text = text;
    }

and

streamPlayer.playStream(textToSpeech.synthesize(
            String.valueOf(text),
            Voice.EN_MICHAEL).execute());

Upvotes: 1

Related Questions