Sye*_*mil 2 android android-looper fusedlocationproviderclient
我正在创建一个位置跟踪应用程序,我正在使用该FusedLocationProviderClient.requestLocationUpdates()方法。它的参数之一需要一个Looper对象,我不完全确定它是如何工作的。现在我只是传递null给它并且它按预期工作。
经过研究,我了解到 UI 线程基本上是一个HandlerThread已经有自己的 Looper 对象的线程(我知道基本的东西,但意识到有点晚了)。Looper.myLooper(所以这次我使用) 而不是 null,它仍然有效。
private void getLocationUpdates(){
//checkSelfPermissions
fusedLocationProviderClient
.requestLocationUpdates(locationRequest,locationCallback,Looper.myLooper());
}
Run Code Online (Sandbox Code Playgroud)
文档说传递null会在调用线程上执行 locationCallback。那么当我使用Looper.myLooper(). 从任何线程调用时两者都有相同的效果还是我遗漏了一些东西?
从文档中添加更多信息:
Callbacks for LocationCallback will be made on the specified thread, which must already be a prepared looper thread.
null在你理解传递和looper作为第三个参数值的区别之前,你需要知道的是: looper// (因为handler你HandlerThread提到了HandlerThread,所以我把它和其他两个放在一起)。
关于这些概念的文章有很多,以下仅供参考:
所以我希望我能尽量简单地回答。
当你说:
I'm creating a location tracking app for which I'm using the FusedLocationProviderClient.requestLocationUpdates() method. One of its argument requires a Looper object and I'm not completely sure how it works. Right now I'm just passing null to it and it works as expected.
我假设你当时没有启动任何新线程(例如: nonew Thread()或 no ),如果是这样,很可能你正在 Android 主线程中调用该方法,即:默认线程,你可以在其中调用该方法更新视图(例如默认情况下您可以毫无问题地运行,这是因为您在主线程中 - 默认情况下也称为 UI 线程),因此传递将在,即:主线程上执行回调。现在你需要知道,主线程有一个循环器,我们可以称之为主循环器。new HandlerThread()getLocationUpdates()textView.setText("xx")nullcalling thread
然后你说:
After researching I learned that the UI Thread is basically a HandlerThread which already has its own Looper object (I know basic stuff but realized a bit late). So I used Looper.myLooper() instead of null this time and it still works.
我假设你做了类似下面的事情:
HandlerThread handlerThread = new HandlerThread();
getLocationUpdates();
private void getLocationUpdates(){
//checkSelfPermissions
fusedLocationProviderClient
.requestLocationUpdates(locationRequest,locationCallback,Looper.myLooper());
}
Run Code Online (Sandbox Code Playgroud)
这次您Looper.myLooper()作为第三个参数传递。
是的,通过这种方式,您提供了一个looper,并且locationCallback将在该特定线程上执行looper(稍后讨论一下 Looper )。
但是,因为您很可能getLocationUpdates()再次在主线程中调用,所以Looper.myLooper仍然返回主线程中的循环程序,是的,您可以认为callback仍然在主循环程序中运行,与上面设置的相同null。
但是,如果您将代码更改为如下所示:
HandlerThread handlerThread = new HandlerThread();
handlerThread.start();
getLocationUpdates(handlerThread.getLooper());
private void getLocationUpdates(Looper looper){
//checkSelfPermissions
fusedLocationProviderClient
.requestLocationUpdates(locationRequest, locationCallback, looper);
}
Run Code Online (Sandbox Code Playgroud)
将callback在指定的 Looper 线程上执行,即:从 中获取的 Looper 对象handler.getLooper()。
那么到底有什么区别呢?
当您创建一个 newHandlerThread并启动它时,您将启动一个 new Thread,并且默认情况下handlerThread.start()将调用,处理程序线程在此处创建一个 new ,并且该循环器已准备就绪,与您刚才创建的循环器绑定在一起。HandlerThread#run()looperhandlerThread
如果您尝试在回调中更新 UI 元素(例如更新文本视图或地图视图),您将看到真正的区别。因为 UI 更新只允许在 UI 线程上进行,如果你设置了,handlerThread.getLooper()那么在尝试更新 UI 时将会遇到异常;而如果从主线程null设置或则不会有问题,之所以强调是因为,在不同线程上运行时会引用不同的looper对象。Looper.myLooper() main threadLooper.myLooper
谈谈looper:有了对象looper,您可以新建一个处理程序并将looper传递给它,例如:Handler handler = new Handler(looper),然后当您调用 时handler.post(new Runnable(...)),可运行对象将在您在处理程序上设置的looper线程上执行,我认为这就是API 在幕后进行。
handler我认为阅读更多有关//looper的文章HandlerThread会有帮助。
| 归档时间: |
|
| 查看次数: |
7390 次 |
| 最近记录: |