Reputation: 143
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!
Upvotes: 8
Views: 23090
Reputation: 49817
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();
}
}
Upvotes: 9
Reputation: 16043
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.
Upvotes: 21