从Thread更新TextView仅在Thread之后更新

时间:2014-01-27 23:35:25

标签: android multithreading android-fragments textview

我正在尝试制作一本类似书籍的应用程序,其中包含图片和文字。我已经使用了片段,并添加了一个语音,当片段页面可见时开始播放,当片段页面不可见时停止播放。

我现在正试着突出一个词,因为它在声音中说。到目前为止,这是我的代码

在片段中:

    @Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

    // Make sure that we are currently visible
    if (this.isVisible()) {

        if(MainActivity.soundOn){
            if(!MainActivity.mediaPlayer.isPlaying()){
                try {
                    MainActivity.mediaPlayer.prepare();
                } catch (IllegalStateException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                MainActivity.mediaPlayer.start();
                MainActivity.start(getActivity(), sentence);
            }

            //MainActivity.test(sentence);
            MainActivity.mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    //MainActivity.start();
                }
            });
        }
        // If we are becoming invisible, then...
        if (!isVisibleToUser || !MainActivity.soundOn) { 
            stopPlaying(getActivity());
        }

    }
}

主要活动:

public static void start(Activity activity, Sentence sent){
    //textControl.start();
    try{
        player = new Player(activity);
        player.set(sent, textControl);

        textControl.draw(sent, sent.words.get(0));

                    //while the mediaplayer is playing the voice over
        while(mediaPlayer.isPlaying())
        {
            player.run();
        }
    }
    catch(Exception e){
        e.printStackTrace();
    }

线程,我已经删除了大部分代码用于测试和readablitly:

    class Player extends Thread{

public int time;
public TextController control;
public int i = 1;
TextView tv;

private WeakReference<Activity> mActivity;
private Sentence sentence = null;

public Player(Activity activity) {
    mActivity = new WeakReference<Activity>(activity);
}

public void set(Sentence _sentence, TextController _control){
    sentence = _sentence;
    control = _control;
}


@Override
public void run()
{

    final Activity activity = mActivity.get();

    tv = (TextView) activity.findViewById(R.id.textView1);

        activity.runOnUiThread(new Runnable() {

            public void run() {

                    tv.setText("Testing");
                                //other stuff
            }
        });
    }
}

我想知道为什么代码“tv.setText(”Testing“);”执行后不会立即更新textview吗?而是在setUserVisibleHint(boolean isVisibleToUser)方法完成后的某个时候更新textview。

我也对更好的方法提出建议。

如果您想了解更多有关任务和问题的背景信息,请随意提问,因为我已经将其简短了一下,谢谢!

带有textView的片段的XML:

<?xml version="1.0" encoding="utf-8"?>
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="horizontal"
  android:onClick="toggleAction">

<TextView
    android:id="@+id/textView1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical"
    android:gravity="center_horizontal"
    android:text="@string/fragment1"
    android:textSize="50sp" />

</LinearLayout>

2 个答案:

答案 0 :(得分:1)

我无法使用此线程解决此问题,因此尝试使用AsyncTask。通过更新onProgressUpdate

中的TextView,这非常有效
@Override
protected void onProgressUpdate(Spannable... result){
    view.setText(result[0]);
    view.invalidate();
}

答案 1 :(得分:0)

正如您所说,您在Thread内运行此功能。一旦你提到这个令很多人害怕的词,你就必须意识到,你现在拥有更多(与你拥有的线程一样多),而不是只有一种执行方式。这意味着每个线程都不会执行其代码,就好像它只是UI线程一样,人们可能会认为代码是经常运行的,但现在每个Thread都有优先级并且它们同时运行,并且还要记住可能有像synchronized方法/实例这样的元素阻止(暂时)执行某些代码,这会让你怀疑为什么会这样做某些命令比“应该”更晚或更早执行。

话虽如此,一旦你进入多线程世界,虽然它非常通用且非常强大,但你必须记住你的代码的某些部分必须同步才能得到预期的结果。如前所述,实现此目的的一种方法是synchronized保留字。您可以将它分配给方法和实例。关于这一点,可能会找到一个非常好的阅读there

同步执行工作流的其他方法是选择本机实现并发访问/插入/修改/删除控件的一些数据类型,因此您不必为此而烦恼,并避免为什么会出现并发异常的巨大麻烦。您可以找到这些结构的列表here

您还有其他同步机制。其中两个,可能最受欢迎的是SemaphoreCountDownLatch es。我个人更喜欢最后一个,因为它为处理类间甚至方法间同步提供了很大的多功能性。可以在developer reference page上找到一个很好的例子。