【问题标题】:fusedLocationProvider running on main thread, even if method is called from different runnable threadfusedLocationProvider 在主线程上运行,即使方法是从不同的可运行线程调用的
【发布时间】:2021-04-27 18:20:33
【问题描述】:
  autoSearch_button.setOnClickListener(view -> {
        grant_permission();
        check_location_enableornot();
        lastButton_pressed = view.getId();
        ExampleRunnable exampleRunnable = new ExampleRunnable(20);
        Thread thread = new  Thread(exampleRunnable);
        thread.start();
        thread.join();
    });
 
  public class ExampleRunnable implements Runnable {
    private int kmRadius;
    private double lat =0 , longi =0 ;

    public ExampleRunnable(int i) {
        this.kmRadius = i;
    }

    @Override
    public void run() {
        lastLocation();
    }  
    
    private void lastLocation(){
        Log.i(TAG, "lastLocation: " + Thread.currentThread().getName());
        
       fusedLocationProviderClient =  LocationServices.getFusedLocationProviderClient(MainActivity.this);
       // for now being assume that i have declared     
      @SuppressLint("MissingPermission") Task<Location> locationTask = fusedLocationProviderClient.getLastLocation();
        locationTask.addOnSuccessListener(location -> {
            if (location != null) {
                //We have a location
                Log.d(TAG, "run: last location" +  Thread.currentThread().getName()););
                this.lat = location.getLatitude();
                this.longi = location.getLongitude();
                print();
            } else  {
                Log.d(TAG, "onSuccess: Location was null... calling robust");
            }
        }).addOnFailureListener(e -> Log.e(TAG, "onFailure: " + e.getLocalizedMessage() ));
      }
    }
   
    public synchronized void print(){
      Log.d(TAG, "print: " + Thread.currentThread.getName());
    }
 }

在 logcat 中输出我想要的内容

  • 最后一个位置:thread4
  • 运行:lastLocation thread4
  • 打印:thread4

但是我得到了什么结果- 最后位置:线程4 // 运行:lastLocation main // 打印:主要

我想在特定线程中处理位置并对其进行处理

【问题讨论】:

    标签: java android multithreading performance location


    【解决方案1】:

    locationTask.addOnSuccessListener

    这不会运行侦听器,它只是注册locationTask 对象后面的代码块,并且该对象可以用它做任何事情。

    显然(这在这样的事件处理程序系统中很常见),某个线程最终会执行某个事件,因此,该事件的侦听器会立即在该线程中运行。

    您有两种解决方案:

    1. 导致任何事件最终触发侦听器(您的代码无助于解释它在哪里;导致变量locationTask 指向的对象进入“成功”状态,从而触发您的侦听器)发生在您希望它发生的线程中,而不是主线程中。

    2. 不要启动线程来注册成功监听器;在你的成功监听器中启动一个线程(所以不要Log.d(TAG, "run: last location"...,而是启动一个线程)。

    有时,事件处理程序系统是可配置的,您可以告诉它在其他线程中触发此类事件,但这种情况很少见。如果库不支持它(我怀疑它支持),你必须编写包装方法或包装整个库来获得它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-03
      • 1970-01-01
      相关资源
      最近更新 更多