I have the following working flow of my application: main activity has a button which starts the second activity after the click. In the second activity there is a TextView
which shows the city which located in the specified geopoint. To find this city I make a request to Geocoder which I make in the background thread.
What I expect: second activity starts (almost) immediately, when background thread finishes the request, ui thread updates the TextView
content.
What happens: the second activity gets started only when Geocoder
finishes its job. To make it obvious we can turn off the wi-fi and click on the button - five-six seconds of expectation, and right after the message that tells that Geocoder
couldn't get the geopoint appears in the log, the second activity launches.
What I'm doing wrong? The relevant code is below, the full sample project is on github.
public class SecondActivity extends Activity implements Handler.Callback {
private HandlerThread mHandlerThread = new HandlerThread("BackgroundThread");
private Handler mUIHandler;
private Handler mBackgroundHandler;
private TextView mLocationView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
mLocationView = (TextView) findViewById(R.id.location_name);
mUIHandler = new Handler(getMainLooper(), this);
mHandlerThread.start();
mBackgroundHandler = new Handler(mHandlerThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
if (msg.what == 0) {
final Geocoder geocoder = new Geocoder(SecondActivity.this);
try {
final List<Address> results = geocoder.getFromLocation(53.539316, 49.396494, 1);
if (results != null && !results.isEmpty()) {
mUIHandler.dispatchMessage(Message.obtain(mUIHandler, 1, results.get(0)));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
}
@Override
protected void onResume() {
super.onResume();
mBackgroundHandler.dispatchMessage(Message.obtain(mBackgroundHandler, 0));
}
@Override
public boolean handleMessage(Message msg) {
if (msg.what == 1) {
mLocationView.setText("I live in " + ((Address) msg.obj).getLocality());
return true;
}
return false;
}
}