how to use runnable in android
Asked Answered
C

4

5

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

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

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 serviceResolved is executed from the Discovery class a while after the application starts and should update the textview (from MainTest class). But this does not happen. How do I fix this behaviour? I think it might be a Runnable problem.

Charla answered 11/9, 2012 at 9:15 Comment(3)
Do you want to execute ur "serviceResolved" as background operation?Bullbat
Just echoing what Ads said, it appears you are doing all work on the UI thread already, so no need to post back to the UI thread. However, it looks like you intended to do background/multithread workMuffle
the serviceResolved is automatically executed as Background by Jmdns packageCharla
P
4

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

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 runOnUiThread in your activity class (MainTest.java). For example:

public void updateView () {
    this.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            String msg = discovery.getMsg();
            textView.setText(msg);
        }
    });
}
Paedogenesis answered 11/9, 2012 at 9:22 Comment(0)
C
6

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();
}
Cliffordclift answered 11/9, 2012 at 9:23 Comment(0)
P
4

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

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 runOnUiThread in your activity class (MainTest.java). For example:

public void updateView () {
    this.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            String msg = discovery.getMsg();
            textView.setText(msg);
        }
    });
}
Paedogenesis answered 11/9, 2012 at 9:22 Comment(0)
M
0

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.

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();
Muffle answered 11/9, 2012 at 9:47 Comment(0)
L
0

It works :)

final Handler handler = new Handler();
handler.post(new Runnable() {
     @Override
     public void run() {
     /* ... */
     handler.postDelayed(this, 15000);
     }
});
Linettelineup answered 6/6, 2018 at 3:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.