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.
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();
}
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);
}
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With