0

次の問題があります。ルーパーを使用したスレッドのこの実装があります。

public class GeoLocationThread extends Thread{

public Handler handler;
private General general;


public void run(){
    Looper.prepare();       
    handler = new IncomingHandler(general);
    Looper.loop();          

}

public GeoLocationThread(General general){
    this.general=general;
}



private static class IncomingHandler extends Handler{
    private final WeakReference<General> mService; 

    IncomingHandler(General service) {
        mService = new WeakReference<General>(service);
    }

    @Override
    public void handleMessage(Message msg)
    {
         General service = mService.get();
         if (service != null) {
             Location location=service.getLl().getLocation();
                if(location.getAccuracy()<40){                                                                                      
                    service.setOrigin(new GeoPoint((int) (location.getLatitude() * 1E6),(int) (location.getLongitude() * 1E6)));
                }
         }
    }

}

}

そして、私は次のことをしたいと思います:

GeoLocationThread locationThread=new GeoLocationThread(this);
locationThread.start();
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, ll, locationThread.handler.getLooper());

lm は LocationManager です。私のログとテストからlocationThread.handler.getLooper()、ルーパーの代わりに null を返すと言えます。

なぜそれがヌルなのかわかりません。locationThread.isAlive()trueを返したものを呼び出そうとしました。locationThread.handler;また、null ではないことがわかっているものを取得しようとしました。私もたくさんのグーグルをしましたが、ドキュメンテーション以上のものは見つかりませんでした。

ご回答ありがとうございます。

4

2 に答える 2

2

null操作 2 が互いに同期していないため、コードが読み取られている可能性が最も高いです。が終了して Handler が構築さgetLooper()れるHandlerまで、正常に呼び出すことはできません。Looper.prepare()他のスレッドが実行されている間はブロックされないためThread.start()(もちろん、なぜそうなるのでしょうか? それは新しいスレッドの目的を無効にします) run()、スレッドのブロックとロケーション リスナーを設定しようとするコードとの間に競合状態を作成しました。これにより、誰が最初に実行できるかに基づいて、さまざまなデバイスでさまざまな結果が生成されます。

さらに、位置情報更新の登録は既に非同期プロセスになっているため、なぜセカンダリ スレッドが必要なのか疑問に思うでしょうか? セカンダリを渡さずにリスナーに更新を要求するだけLooperで、リスナーは新しい更新が利用可能になったときに投稿されたデータを取得します。このプロセス中にメインスレッドはブロックされません。

于 2012-07-27T22:13:58.357 に答える
0

コンストラクターで super() を呼び出す必要がありますか? 親コンストラクターが呼び出されていないため、ルーパーが設定されていない可能性がありますか?

わかりました、これを試してください。これ作って:

public class GeoLocationThread extends Thread{

これがあります:

public class GeoLocationThread extends HandlerThread{

次に、ハンドラーを構築するとき、またはルーパーが必要なときに this.getLooper() を実行できます。

于 2012-07-27T20:37:28.853 に答える