执行两个的Runnable的Andr​​oid两个、Runnable、oid、Andr

2023-09-04 03:58:52 作者:半盏清酒

我想提出两个的Runnable为我的Andr​​oid应用程序:

1)可运行R1改变了ImageView的:

 可运行R1 =新的Runnable(){

        @覆盖
        公共无效的run(){
            albumpic.setImageResource(酒馆[I]);
            我++;
            如果(ⅰ> = pub.length){
                I = 0;
            }
            albumpic.postDelayed(这一点,3000);
        }
    };
    albumpic.postDelayed(R1,3000);
 

2)的Runnable R2改变一个TextView:

 的Runnable R2 =新的Runnable(){
           @覆盖
           公共无效的run(){
               OUT =标题:+ retriever.extractMetadata(ShoutCastMetadataRetriever.METADATA_KEY_TITLE)+\ nArtist:+ retriever.extractMetadata(ShoutCastMetadataRetriever.METADATA_KEY_ARTIST);
               title.setText(出);
               title.postDelayed(这一点,3000);
           }
        };
    title.postDelayed(R2,3000);
 

当我运行只是其中之一,它工作正常,但是当我试图运行它们俩他们不工作。

我如何可以使他们的工作既?

谢谢!

更新:我试图用ThreadPoolExecutor的是这样的:

 可运行R1 =新的Runnable(){

        @覆盖
        公共无效的run(){
            albumpic.setImageResource(酒馆[I]);
            我++;
            如果(ⅰ> = pub.length){
                I = 0;
            }
            albumpic.postDelayed(这一点,3000);
        }
    };


    可运行R2 =新的Runnable(){

        @覆盖
        公共无效的run(){
            OUT =标题:+ retriever.extractMetadata(ShoutCastMetadataRetriever.METADATA_KEY_TITLE)+\ nArtist:+ retriever.extractMetadata(ShoutCastMetadataRetriever.METADATA_KEY_ARTIST);
            title.setText(出);
            title.postDelayed(这一点,3000);
        }
    };

    ThreadPoolExecutor的执行人=(的ThreadPoolExecutor)Executors.newFixedThreadPool(2);
    executor.execute(R1);
    executor.execute(R2);
 

和它给了我这些错误:

 十一月5日至15日:56:35.695:E / AndroidRuntime(11437):致命异常:池2线程2
十一月五号至十五号:56:35.695:E / AndroidRuntime(11437):android.view.ViewRoot $ CalledFromWrongThreadException:只有创建视图层次可以触摸其观点原来的线程。
十一月五号至十五号:56:35.695:E / AndroidRuntime(11437):在android.view.ViewRoot.checkThread(ViewRoot.java:3090)
十一月五号至十五号:56:35.695:E / AndroidRuntime(11437):在android.view.ViewRoot.requestLayout(ViewRoot.java:666)
十一月五号至十五号:56:35.695:E / AndroidRuntime(11437):在android.view.View.requestLayout(View.java:8391)
十一月五号至十五号:56:35.695:E / AndroidRuntime(11437):在android.view.View.requestLayout(View.java:8391)
十一月五号至十五号:56:35.695:E / AndroidRuntime(11437):在android.view.View.requestLayout(View.java:8391)
十一月五号至十五号:56:35.695:E / AndroidRuntime(11437):在android.view.View.requestLayout(View.java:8391)
十一月五号至十五号:56:35.695:E / AndroidRuntime(11437):在android.widget.RelativeLayout.requestLayout(RelativeLayout.java:257)
十一月五号至十五号:56:35.695:E / AndroidRuntime(11437):在android.view.View.requestLayout(View.java:8391)
十一月五号至十五号:56:35.695:E / AndroidRuntime(11437):在android.widget.TextView.checkForRelayout(TextView.java:5880)
十一月五号至十五号:56:35.695:E / AndroidRuntime(11437):在android.widget.TextView.setText(TextView.java:2888)
十一月五号至十五号:56:35.695:E / AndroidRuntime(11437):在android.widget.TextView.setText(TextView.java:2749)
十一月五号至十五号:56:35.695:E / AndroidRuntime(11437):在android.widget.TextView.setText(TextView.java:2718)
十一月五号至十五号:56:35.695:E / AndroidRuntime(11437):在com.adventure.agadir.MainActivity $ 11.run(MainActivity.java:241)
十一月五号至十五号:56:35.695:E / AndroidRuntime(11437):在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
十一月五号至十五号:56:35.695:E / AndroidRuntime(11437):在java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:581)
十一月五号至十五号:56:35.695:E / AndroidRuntime(11437):在java.lang.Thread.run(Thread.java:1019)
 

解决方案

您最好使用一个线程池:

 的ThreadPoolExecutor执行人=(的ThreadPoolExecutor)Executors.newFixedThreadPool(INT N);
//正是做平行最大线程固定数量;
executor.execute(runnable1);
executor.execute(runnable2);
 

哦,我明白了。问题是,你正试图在一个TextView从后台线程更改文本,而不是从主threan。对于这样做,你一定要使用Handler-它有点像从主线程的桥梁和后台线程 http://developer.android.com/reference/android/os/Handler.html

所以在你的主类:

 私人最终const int的SWITCH_TEXT_CONTET = 1;
私人处理程序处理程序;
保护无效的onCreate(...){
处理程序=新的处理程序(){
@覆盖
公共无效的handleMessage(信息MSG){
如果(MSG == SWITCH_TEXT_CONTENT)
textView.setText(..);
 

和您可运行:可运行R1 = ...(){ BLA BLA,你的code ......然后handler.sendEmptyMessage(SWITCH_TEXT_CONTENT);} 在这里你去,尝试像瑞士手表这个要去工作

I'd like to make two Runnables work for my Android App:

1) Runnable r1 for changing an 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 for changing a 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);

When I run just one of them it works fine, but when I try to run them both they don't work.

How can I make them work both?

Thanks!

Update: I tried to use the ThreadPoolExecutor like this:

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

And it gave me these errors:

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)

解决方案

you'd better use a 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);

Oh, i see. The problem is that you are trying to change text in a textview from a background thread, not from the main threan. For doing this you got to use Handler- it's kinda like a bridge from the main thread and a background thread http://developer.android.com/reference/android/os/Handler.html

so in your main class :

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(..);

and in your runnable: Runnable r1=....(){ bla bla , your code... and then handler.sendEmptyMessage(SWITCH_TEXT_CONTENT);} here you go, try this gonna work like a swiss watches