如何在android中使用runnable

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12366448/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 10:28:26  来源:igfitidea点击:

how to use runnable in android

androidrunnable

提问by MOHAMED

Hi, I'm newbie in Java Android development and I want to know how to use Runnablein Android. It doesn't seem to be working for me. Here is my source code:

嗨,我是 Java Android 开发的新手,我想知道如何Runnable在 Android 中使用。它似乎对我不起作用。这是我的源代码:

MainTest.java

主测试程序

package com.heeere.androiddnssd.discovery;

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

public class MainTest extends Activity {

    android.net.wifi.WifiManager.MulticastLock lock;
    private Discovery discovery = new Discovery(this); 
    private TextView textView;

    /** Called when the activity is first created. */
    @SuppressLint("NewApi") @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        textView = (TextView)this.findViewById(R.id.text);

        android.net.wifi.WifiManager wifi = (android.net.wifi.WifiManager) getSystemService(android.content.Context.WIFI_SERVICE);
        lock = wifi.createMulticastLock("mylockthereturn");
        lock.setReferenceCounted(true);
        lock.acquire();

    }

    public void updateView () {
        String msg = discovery.getMsg();
        textView.setText(msg);
    }

    @SuppressLint("NewApi") @Override
    protected void onStop() {
        discovery.stop();
        lock.release();
        super.onStop();
    }


}

Discovery.java

发现.java

package com.heeere.androiddnssd.discovery;

import java.io.IOException;

import javax.jmdns.JmDNS;
import javax.jmdns.ServiceEvent;
import javax.jmdns.ServiceListener;

public class Discovery {


    private String type = "_ikunet._tcp.local.";
    private String msg="";
    private JmDNS jmdns = null;
    private ServiceListener listener = null;
    private MainTest maintest;
    android.os.Handler handler = new android.os.Handler();

    public Discovery (MainTest maintest) {
        this.maintest = maintest;
        setUp();
    }

    private void setUp() {

        try {
            jmdns = JmDNS.create();
            jmdns.addServiceListener(type, listener = new ServiceListener() {

                public void serviceResolved(ServiceEvent ev) {
                    msg = msg + ev.getInfo().getName()+ "\n";
                    update();
                }

                public void serviceRemoved(ServiceEvent ev) {
                }

                public void serviceAdded(ServiceEvent event) {
                    jmdns.requestServiceInfo(event.getType(), event.getName(), 1);
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
    }

    public String getMsg() {
        return msg;
    }

    private void update() {
        handler.postDelayed(new Runnable() {
            public void run() {
                maintest.updateView();
            }
        }, 1);
    }


    public void stop() {
        if (jmdns != null) {
            if (listener != null) {
                jmdns.removeServiceListener(type, listener);
                listener = null;
            }
            jmdns.unregisterAllServices();
            try {
                jmdns.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            jmdns = null;
        }
    }

}

main.xml

主文件

<?xml version="1.0" encoding="utf-8"?>

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scroller"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:fillViewport="true">
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent" 
              android:layout_height="fill_parent" 
              android:orientation="vertical"
              android:scrollbars="vertical"
              android:fadeScrollbars="true"
              android:isScrollContainer="true">
    <TextView  
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content" 
            android:text="Hello World, Android Discovery" />
    <TextView 
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello, I am a TextView" />
    <Button 
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello, I am a Button" />
    </LinearLayout>
</ScrollView>

The serviceResolvedis executed from the Discoveryclass a while after the application starts and should update the textview(from MainTestclass). But this does not happen. How do I fix this behaviour? I think it might be a Runnableproblem.

serviceResolved从执行Discovery而在应用程序启动后,应该更新类textview(从MainTest类)。但这不会发生。我该如何解决这种行为?我认为这可能是一个Runnable问题。

回答by waqaslam

You may skip using Runnableas it seems unnecessary in Discovery.java. For example:

您可以跳过使用,Runnable因为它在 Discovery.java 中似乎没有必要。例如:

private void update() {
    maintest.updateView();
}

However, in case you are using thread to gather search results then what you can do is to make use of runOnUiThreadin your activity class (MainTest.java). For example:

但是,如果您使用线程来收集搜索结果,那么您可以做的是runOnUiThread在您的活动类 (MainTest.java) 中使用。例如:

public void updateView () {
    this.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            String msg = discovery.getMsg();
            textView.setText(msg);
        }
    });
}

回答by user1049280

try this

尝试这个

private void update() {
    final Runnable r = new Runnable() {
        public void run() {
            maintest.updateView();
            handler.postDelayed(this, 1000);
        }
    };
    handler.postDelayed(r, 1000);
}

But I would recommend you this:

但我会向你推荐这个:

private void update() {
new Thread() {
    public void run() {
        while (true) {
            runOnUiThread(new Runnable() {
                 @Override
                 public void run() {
                      maintest.updateView();
                 }
            });
            Thread.sleep(1000);
        } 
    }
}.start();
}

回答by pjco

Personally I would use the handler a bit differently.

我个人会稍微不同地使用处理程序。

To me the Handler should be created by the Activity and handed to your discovery class. This is better because you avoid "leaking" the entire Activity.

对我来说,处理程序应该由 Activity 创建并交给您的发现类。这更好,因为您可以避免“泄漏”整个 Activity。

In the activity you would have

在活动中你会有

private final Handler mHandler = new Handler() 
{
    @Override
    public void handleMessage(Message msg)
    {
        switch (msg.what) 
        {
            case UPDATE_PROGRESS:                   
                handleUpdateProgress();
                break;               
        }
    }   
};

Then, if you need to post back to the activity you can use something like:

然后,如果您需要回发到活动,您可以使用以下内容:

handlerFromActivity.obtainMessage(UPDATE_PROGRESS).sendToTarget();

回答by Woottipong Kongsib

It works :)

有用 :)

final Handler handler = new Handler();
handler.post(new Runnable() {
     @Override
     public void run() {
     /* ... */
     handler.postDelayed(this, 15000);
     }
});