从不同的线程修改一个Android视图 [英] Modifying an Android view from a different thread

查看:229
本文介绍了从不同的线程修改一个Android视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Android上,活动的主UI线程运行和文字转语音引擎在不同的线程中运行。我想在一个活动来更新视图中的文字转语音引擎完成播放话语时。

On Android, activities run in the main UI thread and the TextToSpeech engine runs in a different thread. I want to update a view in an activity when the TextToSpeech engine completes playing back an utterance.

如果我忽略这一点,然后我得到的时候文字转语音引擎调用活动实例的 android.view.ViewRoot $ CalledFromWrongThreadException 错误。

If I ignore this, then I get an android.view.ViewRoot$CalledFromWrongThreadException error when the TextToSpeech engine calls the Activity instance.

下面是我的code。在MainActivity.java脚本的最后一行出现的错误。

Here's my code. The error occurs on the last line of the MainActivity.java script.

TTSUser.java

TTSUser.java

package com.example.thread;

interface TTSUser {
  void ttsUtteranceComplete();
}

MainActivity.java

MainActivity.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);
  }
}

TTS.java

TTS.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文本可以识别

I also added a line to the TextView definition in activity_main.xml, so that the Hello World text can be identified.

    android:id="@+id/hello_world"

要措词类似问题的其他答案假设其他线程在code明确创建。这里,线程为文字转语音引擎隐式地创建。我怎样才能改变我的code,使MainActivity.java的最后一行不会抛出一个错误?

Other answers to similarly-worded questions assume that the other thread is created explicitly in the code. Here, the thread for the TextToSpeech engine is created implicitly. How can I change my code so that the last line of MainActivity.java does not throw an error?

推荐答案

要在UI线程上执行的东西时,它的外面,你可以使用的方法 runOnUiThread(Runnable接口)属于活动

To execute something on the UI thread when outside of it, you can use the method runOnUiThread(Runnable) that belongs to Activity.

所以,你可以这样做:

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
  }
});

这篇关于从不同的线程修改一个Android视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆