2

アプリケーションの次の作業フローがあります。メイン アクティビティには、クリック後に 2 番目のアクティビティを開始するボタンがあります。2 番目のアクティビティにはTextView、指定されたジオポイントにある都市を示す があります。この都市を見つけるために、バックグラウンド スレッドで作成するGeocoderにリクエストを送信します。

私が期待すること: 2 番目のアクティビティが (ほぼ) すぐに開始され、バックグラウンド スレッドが要求を終了すると、UI スレッドがTextViewコンテンツを更新します。

何が起こるか: 2 番目のアクティビティは、そのジョブが終了したときにのみ開始されます。GeocoderWi-Fi をオフにしてボタンをクリックできることを明確にするために、5 ~ 6 秒Geocoder待ち、ジオポイントを取得できなかったことを示すメッセージがログに表示された直後に、2 番目のアクティビティが起動します。

私が間違っていることは何ですか?関連するコードを以下に示します。完全なサンプル プロジェクトは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 に答える