执行两个Runnables Android

时间:2013-05-15 11:05:14

标签: android multithreading runnable threadpoolexecutor

我想让两个Runnables适用于我的Android应用程序:

1)Runnable r1用于更改ImageView:

        Runnable r1 = new Runnable() {

        @Override
        public void run() {
            albumpic.setImageResource(pub[i]);
            i++;
            if(i >= pub.length) {
                i = 0;
            }
            albumpic.postDelayed(this, 3000);
        }
    }; 
    albumpic.postDelayed(r1, 3000);

2)Runnable r2用于更改TextView:

        Runnable r2 = new Runnable(){
           @Override
           public void run(){
               out =  "Title: " + retriever.extractMetadata(ShoutCastMetadataRetriever.METADATA_KEY_TITLE) + " \nArtist: " + retriever.extractMetadata(ShoutCastMetadataRetriever.METADATA_KEY_ARTIST);
               title.setText(out);
               title.postDelayed(this, 3000);
           }   
        };
    title.postDelayed(r2, 3000);

当我只运行其中一个时它工作正常,但是当我尝试运行它们时它们都不起作用。

如何使它们兼顾?

谢谢!

更新:我试图像这样使用ThreadPoolExecutor:

Runnable r1 = new Runnable() {

        @Override
        public void run() {
            albumpic.setImageResource(pub[i]);
            i++;
            if(i >= pub.length) {
                i = 0;
            }
            albumpic.postDelayed(this, 3000);
        }
    }; 


    Runnable r2 = new Runnable() {

        @Override
        public void run() {
            out =  "Title: " + retriever.extractMetadata(ShoutCastMetadataRetriever.METADATA_KEY_TITLE) + " \nArtist: " + retriever.extractMetadata(ShoutCastMetadataRetriever.METADATA_KEY_ARTIST);
            title.setText(out);
            title.postDelayed(this, 3000);
        }
    }; 

    ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
    executor.execute(r1);
    executor.execute(r2);

它给了我这些错误:

05-15 11:56:35.695: E/AndroidRuntime(11437): FATAL EXCEPTION: pool-2-thread-2
05-15 11:56:35.695: E/AndroidRuntime(11437): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
05-15 11:56:35.695: E/AndroidRuntime(11437):    at android.view.ViewRoot.checkThread(ViewRoot.java:3090)
05-15 11:56:35.695: E/AndroidRuntime(11437):    at android.view.ViewRoot.requestLayout(ViewRoot.java:666)
05-15 11:56:35.695: E/AndroidRuntime(11437):    at android.view.View.requestLayout(View.java:8391)
05-15 11:56:35.695: E/AndroidRuntime(11437):    at android.view.View.requestLayout(View.java:8391)
05-15 11:56:35.695: E/AndroidRuntime(11437):    at android.view.View.requestLayout(View.java:8391)
05-15 11:56:35.695: E/AndroidRuntime(11437):    at android.view.View.requestLayout(View.java:8391)
05-15 11:56:35.695: E/AndroidRuntime(11437):    at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:257)
05-15 11:56:35.695: E/AndroidRuntime(11437):    at android.view.View.requestLayout(View.java:8391)
05-15 11:56:35.695: E/AndroidRuntime(11437):    at android.widget.TextView.checkForRelayout(TextView.java:5880)
05-15 11:56:35.695: E/AndroidRuntime(11437):    at android.widget.TextView.setText(TextView.java:2888)
05-15 11:56:35.695: E/AndroidRuntime(11437):    at android.widget.TextView.setText(TextView.java:2749)
05-15 11:56:35.695: E/AndroidRuntime(11437):    at android.widget.TextView.setText(TextView.java:2718)
05-15 11:56:35.695: E/AndroidRuntime(11437):    at com.adventure.agadir.MainActivity$11.run(MainActivity.java:241)
05-15 11:56:35.695: E/AndroidRuntime(11437):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
05-15 11:56:35.695: E/AndroidRuntime(11437):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
05-15 11:56:35.695: E/AndroidRuntime(11437):    at java.lang.Thread.run(Thread.java:1019)

1 个答案:

答案 0 :(得分:3)

您最好使用ThreadPool:

ThreadPoolExecutor executor=(ThreadPoolExecutor) Executors.newFixedThreadPool(int n);
//n-is a fixed number of maximum threads to do parallel;
executor.execute(runnable1);
executor.execute(runnable2);

哦,我明白了。问题是您尝试从后台线程更改textview中的文本,而不是从主threan更改。为了做到这一点,你必须使用Handler-它有点像主线程和后台线程的桥梁 http://developer.android.com/reference/android/os/Handler.html

所以在你的主要班级:

private final const int SWITCH_TEXT_CONTET=1;
private Handler handler;
protected void onCreate(...){
handler=new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg==SWITCH_TEXT_CONTENT)
textView.setText(..);

并在您的runnable中:Runnable r1=....(){ bla bla , your code... and then handler.sendEmptyMessage(SWITCH_TEXT_CONTENT);} 在这里,你试试这个就像瑞士手表一样工作