I'm trying to monitor network connectivity on android. This cannot be done on the main thread, so the data collection occurs on a separate thread I spawn - and I'm learning to use the Handler class to report back to the UI every second. Here's the relevant snippets of my code...
public class MainActivity extends Activity {
private TextView textView;
private int linkSpeed;
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
Message message = msg;
textView.setText(message);
setContentView(textView);
}
};
/** Called when the activity is created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
textView = new TextView(this);
textView.setTextSize(25);
Thread thread = new Thread() {
public void run() {
for (;;) {
try {
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
while (true)
{
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
if (wifiInfo != null) {
linkSpeed = wifiInfo.getLinkSpeed(); //measured using WifiInfo.LINK_SPEED_UNITS
}
else {
linkSpeed = -1;
}
}
String message = "linkSpeed = " + linkSpeed;
handler.handleMessage(message);
Thread.sleep(1000);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
};
thread.start();
}
The problem is, the message I get from the new thread I spawn is of type "String", but I cannot seem to overload the handleMessage method in the Handler class to take Strings instead of Messages. I don't think there's a direct conversion between Strings and Messages, as the only method in the Message class that returns a String is the toString() method, but it returns a description, rather than what the message contains. I'm also confused as to how I can convert a String to a Message - and I feel like I'm doing a very roundabout approach. Any help would be greatly appreciated!
You don't have to overload or try to do any coversions between String
and Message
.
What you should do, is to put that String into an object of type Message and sent it to the Handler
. Then in handleMessage()
extract the String from the Message.
Something like this:
// ....
String message = "linkSpeed = " + linkSpeed;
Message msg = Message.obtain(); // Creates an new Message instance
msg.obj = message; // Put the string into Message, into "obj" field.
msg.setTarget(handler); // Set the Handler
msg.sendToTarget(); //Send the message
//....
And in handleMessage()
:
@Override
public void handleMessage(Message msg) {
String message = (String) msg.obj; //Extract the string from the Message
textView.setText(message);
//....
}
But besides this, the program has an issue: you won't be able to send the data to the handler because that part of the code is unreachable:
while (true) {
WifiInfo s = wifiManager.getConnectionInfo();
//..
}
String message = "linkSpeed = " + linkSpeed; // This line never won't be reached.
Also, don't forget to stop the Thread
at some time, otherwise it will continue to run even after the app is closed.
You can attach objects - like your String - to your Message objects using a Bundle.
I have created this example:
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
public class MainActivity extends Activity {
Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg) {
Bundle bundle = msg.getData();
String text = bundle.getString("key");
// text will contain the string "your string message"
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread thread = new Thread()
{
@Override
public void run() {
Message message = handler.obtainMessage();
Bundle bundle = new Bundle();
bundle.putString("key", "your string message");
message.setData(bundle);
handler.sendMessage(message);
}
};
thread.start();
}
}
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