How to manage Loopers and Threads (thread doesn't die anymore!)

五迷三道 提交于 2019-12-03 12:23:11

You can explicitly quit from Looper's loop using Handler:

private Handler mUserLocationHandler = null;
private Handler handler = null;

public class UserLocationThread extends Thread implements LocationListener {    

 public void run() {
    try {
          Looper.prepare();
        mUserLocationHandler = new Handler();
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
        Looper.loop();

    } catch (Exception e) {
        //...
    }
}


@Override
public void onLocationChanged(Location location) {
    locationManager.removeUpdates(this);
    //...
    handler.sendMessage(msg); 
    if(mUserLocationHandler != null){
        mUserLocationHandler.getLooper().quit();
    }
}

"I implemented this as a tread because it has to be started on request and do its work just for a limited time."

This sounds like a perfect reason to simply reuse the main looper. There's no need to spawn a new Thread here. If you're doing blocking work (network I/O, etc) in onLocationChanged(), at that point you could spin up an ASyncTask.

Implement LocationListener on your Activity/Service or whatever and let it use the main looper by default.

Spawning a new thread, setting it to loop, and then immediately quitting is unnecessary.

IntentService is good for do this job.

IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.

Looper().quit(); is good, and according to specification:

Causes the loop() method to terminate without processing any more messages in the message queue.

But, if you have a task that already is under processing, and you want to stop it too, you can acquire working thread and cause it to interrupt:

@Override
public void onLocationChanged(Location location) {
    locationManager.removeUpdates(this);
    handler.sendMessage(msg); //this is the handler for communication with father thread
    if(mUserLocationHandler != null){
        mUserLocationHandler.getLooper().quit();
        mUserLocationHandler.getLooper().getThread().interrupt(); // <-- here
    }

}

This works fine with most IO, and thread locking/waiting.

Extend the AsyncTask class. It does all the threading and handling for you automatically.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!