我的应用程序有以下工作流程:main活动有一个按钮,在单击后启动第二个活动。在第二个活动中有一个TextView
,它显示位于指定地理位置的城市。为了找到这个城市,我向Geocoder提出了我在后台主题中提出的请求。
我的期望:第二个活动立即开始(几乎),当后台线程完成请求时,ui线程更新TextView
内容。
会发生什么:当Geocoder
完成其工作时,第二个活动仅启动 。为了显而易见,我们可以关闭wi-fi并点击按钮 - 期望的五六秒,并且在消息告知Geocoder
无法获得地理点出现在日志中之后,第二项活动启动。
我做错了什么?相关代码如下,完整的示例项目为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;
}
}
答案 0 :(得分:1)
我同意CommonsWare,使用AsyncTask可以让您的生活更轻松。只需根据需要调整参数和返回类型,或将变量保存在全局范围内。
new AsyncTask<Void, Void, Void>()
{
@Override
protected Void doInBackground(Void... params)
{
// Your Geolocation operation goes here
return null;
}
@Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
// This is called when your operation is completed
}
}.execute();