2

我的应用程序有以下工作流程:主活动有一个按钮,单击后启动第二个活动。在第二个活动中,有一个TextView显示位于指定地理点的城市。为了找到这个城市,我向我在后台线程中提出的Geocoder提出了一个请求。

我的期望:第二个活动(几乎)立即开始,当后台线程完成请求时,ui线程更新TextView内容。

会发生什么:第二个活动只有Geocoder完成其工作时才开始。为了清楚起见,我们可以关闭 wi-fi 并单击按钮 - 预计五六秒,Geocoder在日志中出现无法获取地理点的消息后,第二个活动启动。

我做错了什么?相关代码如下,完整的示例项目在 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;
    }
}
4

1 回答 1

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();
于 2014-10-02T17:39:03.500 回答