gpt4 book ai didi

java - 从不同线程修改 Android View

转载 作者:行者123 更新时间:2023-11-30 09:00:37 31 4
gpt4 key购买 nike

在 Android 上, Activity 在主 UI 线程中运行,而 TextToSpeech 引擎在不同的线程中运行。我想在 TextToSpeech 引擎完成播放话语时更新 Activity 中的 View 。

如果我忽略它,那么当 TextToSpeech 引擎调用 Activity 实例时,我会得到一个 android.view.ViewRoot$CalledFromWrongThreadException 错误。

这是我的代码。错误发生在 MainActivity.java 脚本的最后一行。

TTSUser.java

package com.example.thread;

interface TTSUser {
void ttsUtteranceComplete();
}

主 Activity .java

package com.example.thread;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity implements TTSUser {

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

new TTS(this);
}

public void ttsUtteranceComplete() {
TextView view_to_hide = (TextView) findViewById(R.id.hello_world);

// On next line: android.view.ViewRoot$CalledFromWrongThreadException:
// Only the original thread that created a view hierarchy can touch its
// views.
view_to_hide.setVisibility(TextView.GONE);
}
}

语音合成.java

package com.example.thread;

import android.app.Activity;
import android.content.Context;
import android.speech.tts.TextToSpeech;

import java.util.HashMap;
import java.util.Locale;

public class TTS implements TextToSpeech.OnInitListener, TextToSpeech.OnUtteranceCompletedListener {

private final String TAG = "callback";
private static TextToSpeech tts;
private TTSUser activity;

public TTS(TTSUser activity) { // Ensures access to ttsUtteranceComplete()
this.activity = activity;
Context context = ((Activity) activity).getApplicationContext();
tts = new android.speech.tts.TextToSpeech(context, this);
}

@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
tts.setLanguage(Locale.UK);
tts.setOnUtteranceCompletedListener(this);
speakText("Hello World");
}
}

public void speakText(String toSpeak) {
int mode = android.speech.tts.TextToSpeech.QUEUE_FLUSH;
// Create an id for this utterance, so that we can call back when it's done
HashMap<String, String> hashMap = new HashMap<String, String>();
hashMap.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, TAG);

tts.speak(toSpeak, mode, hashMap);
}

public void onUtteranceCompleted(String utteranceID) {
if (utteranceID.equals(TAG)) {
activity.ttsUtteranceComplete();
}
}
}

我还在 activity_main.xml 中的 TextView 定义中添加了一行,以便可以识别 Hello World 文本。

    android:id="@+id/hello_world"

类似措辞问题的其他答案假定另一个线程是在代码中显式创建的。在这里,TextToSpeech 引擎的线程是隐式创建的。如何更改我的代码以使 MainActivity.java 的最后一行不引发错误?

最佳答案

要在 UI 线程之外执行某些操作,您可以使用属于 Activity 的方法 runOnUiThread(Runnable)

所以你可以这样做:

activity.runOnUiThread(new Runnable() { // EDIT: ...Ui... requires a lowercase "i"
@Override
public final void run(){
// this runs on UI thread
activity.ttsUtteranceComplete(); // this function will run on the UI thread
}
});

关于java - 从不同线程修改 Android View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26706342/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com