gpt4 book ai didi

android - 在 FusedLocationProviderClient.requestLocationUpdates() 中使用 Looper.myLopper() 或 null 是否相同?

转载 作者:行者123 更新时间:2023-12-05 00:13:49 28 4
gpt4 key购买 nike

我正在创建一个使用 FusedLocationProviderClient.requestLocationUpdates() 的位置跟踪应用程序方法。它的一个论点需要 Looper对象,我不完全确定它是如何工作的。现在我只是通过null到它,它按预期工作。

经过研究,我了解到 UI Thread 基本上是 HandlerThread它已经有自己的 Looper 对象(我知道基本的东西,但意识到有点晚了)。所以我用了Looper.myLooper( ) 而不是 null 这次它仍然有效。

private void getLocationUpdates(){
//checkSelfPermissions
fusedLocationProviderClient
.requestLocationUpdates(locationRequest,locationCallback,Looper.myLooper());
}

文档说通过 null在调用线程上执行 locationCallback。那么当我使用 Looper.myLooper() 时会发生什么? .从字面上的任何线程调用时两者是否具有相同的效果,或者我错过了什么?

最佳答案

document 添加更多信息:Callbacks for LocationCallback will be made on the specified thread, which must already be a prepared looper thread.
在您理解通过 null 之间的区别之前和 looper作为值第三个参数,你需要知道的是:looper/handler/HandlerThread (因为你提到了HandlerThread,所以我把它和其他两个放在一起)。

有很多关于这些概念的文章,这里有一些仅供引用:

  • Understanding Android Core: Looper, Handler, and HandlerThread
  • Android: Looper, Handler, HandlerThread. Part I.
  • Explanation of handler, looper and related android thread classes
  • Looper/Handler vs. Executor


  • 所以我希望我能尽量简单地回答。

    当你说: 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.
    我假设您当时没有启动任何新线程(例如:没有 new Thread() 或没有 new HandlerThread() ),如果是这样,那么您很可能正在调用方法 getLocationUpdates()在 Android 主线程中,即:默认线程,您可以在其上更新 View (例如默认情况下您可以运行 textView.setText("xx") 没有任何问题,这是因为您在主线程中 - 也就是 UI 线程,由默认),所以通过 null将在 calling thread 上执行回调,即:主线程。现在你需要知道,主线程有一个looper,我们可以称它为main looper。

    然后你说: 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());
    }

    这次你通过了 Looper.myLooper()作为第三个参数。

    是的,通过这种方式,您提供了 looper ,以及 locationCallback将在该 looper 的特定线程上执行(稍后再谈一下looper)。

    因为,然而,你很有可能调用 getLocationUpdates()再次在主线程中,所以 Looper.myLooper仍然在主线程中返回 looper,是的,您可以考虑 callback仍在主循环器上运行,与您设置的 null 相同以上。

    但是,如果您像这样更改代码:
    HandlerThread handlerThread = new HandlerThread();
    handlerThread.start();
    getLocationUpdates(handlerThread.getLooper());

    private void getLocationUpdates(Looper looper){
    //checkSelfPermissions
    fusedLocationProviderClient
    .requestLocationUpdates(locationRequest, locationCallback, looper);
    }
    callback将在指定的looper线程上执行,即:你从 handler.getLooper()得到的looper对象.

    那么地球有什么不同呢?

    当你创建一个新的 HandlerThread并开始它,你正在开始一个新的 Thread , 和 handlerThread.start()将调用 HandlerThread#run()默认情况下,处理程序线程创建一个新的 looper ,并且这个弯针已经准备好,与 handlerThread bundle 在一起你刚才创建的。

    如果您尝试在回调中更新 UI 元素(例如更新 textview 或 mapview),您将看到真正的区别。因为仅在 UI 线程上允许 UI 更新,如果您设置 handlerThread.getLooper()那么您在尝试更新 UI 时会遇到异常;设置 null就没有问题或 Looper.myLooper() 来自主线程 , 强调 main thread 的原因是因为, Looper.myLooper在不同线程上运行时会引用不同的 looper 对象。

    谈谈looper:使用 looper对象,您可以新建一个处理程序并将循环器传递给它,例如: Handler handler = new Handler(looper) ,然后当您调用 handler.post(new Runnable(...)) ,runnable 将在您在处理程序上设置的 looper 线程上执行,我认为这就是 API 在幕后所做的。

    阅读更多关于 handler 的文章/ looper/ HandlerThread我认为会有帮助。

    关于android - 在 FusedLocationProviderClient.requestLocationUpdates() 中使用 Looper.myLopper() 或 null 是否相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56728742/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com