Android app LocationManager.registerGnssStatusCallback(), 系统却没有回调onSatelliteStatusChanged(续集)

1. 背景
先看上集
https://blog.csdn.net/xuyongqz/article/details/140774690
app 调用mLocationManager.registerGnssStatusCallback(mCallback) 的时候,接受返回值,如果返回false,delay 500ms,执行retry动作。后期测试的时候,发现goolge这个返回值默认是true,因此要注册的时候,默认delay 500ms处理。

2. bug分析
通过log发现app注册gnss status callback的时间很早,在initializeGnss—mGnssManagerService初始化时间点之前,因为这个时间点mGnssManagerService还未初始化,导致初始化失败。
通过分析log可以知道,上集中的修改仍有问题,那么究竟问题出在哪里呢?为什么app接收了LocationManager::registerGnssStatusCallback的返回值是true,但是仍没有注册成功呢?唯一的解释是android这个接口的返回值异常了,接下来我们从源码出发,一探究竟。

LocationManager::registerGnssStatusCallback的源码如下:按照api说明来看,add成功返回true,而不是注册成功,莫非这里面有坑?

    /**
     * Registers a GNSS status callback.
     *
     * @param callback GNSS status callback object to register
     * @param handler  a handler with a looper that the callback runs on
     * @return true if the listener was successfully added
     *
     * @throws IllegalArgumentException if callback is null
     * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
     */
    @RequiresPermission(ACCESS_FINE_LOCATION)
    public boolean registerGnssStatusCallback(
            @NonNull GnssStatus.Callback callback, @Nullable Handler handler) {
        if (handler == null) {
            handler = new Handler();
        }

        try {
            return mGnssStatusListenerManager.addListener(callback, handler);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
        public boolean addListener(@NonNull GpsStatus.Listener listener, @NonNull Executor executor)
                throws RemoteException {
            return addInternal(null, listener, executor);
        }
```java
    public boolean addListener(@Nullable TRequest request, @NonNull TListener listener,
            @NonNull Executor executor) throws RemoteException {
        return addInternal(request, listener, executor);
    }

    protected final boolean addInternal(@Nullable TRequest request, @NonNull Object listener,
            @NonNull Handler handler) throws RemoteException {
        return addInternal(request, listener, new HandlerExecutor(handler));
    }

    protected final boolean addInternal(@Nullable TRequest request, @NonNull Object listener,
            @NonNull Executor executor)
            throws RemoteException {
        Preconditions.checkArgument(listener != null, "invalid null listener/callback");
        return addInternal(listener, new Registration<>(request, executor, convertKey(listener)));
    }

    private boolean addInternal(Object key, Registration<TRequest, TListener> registration)
            throws RemoteException {
        Preconditions.checkNotNull(registration);

        synchronized (mLock) {
            boolean initialRequest = mListeners.isEmpty();

            ArrayMap<Object, Registration<TRequest, TListener>> newListeners = new ArrayMap<>(
                    mListeners.size() + 1);
            newListeners.putAll(mListeners);
            Registration<TRequest, TListener> oldRegistration = newListeners.put(key,
                    registration);
            mListeners = newListeners;

            if (oldRegistration != null) {
                oldRegistration.unregister();
            }
            TRequest merged = mergeRequests();

            if (initialRequest || !Objects.equals(merged, mMergedRequest)) {
                mMergedRequest = merged;
                if (!initialRequest) {
                    unregisterService();
                }
                registerService(mMergedRequest);---这里才会调用LocationManagerService的registerGnssStatusCallback,但是没有接收返回值。
            }

            return true;---问题出在这里,直接返回了true
        }
    }

分析到这里,我们终于明白了,LocationManager的registerGnssStatusCallback的返回值,并没有接收LocationManagerService的registerGnssStatusCallback的返回值,而是默认返回的true。所以上集中解决方案有问题。经过和app模块讨论,最终我们决定app注册的时候,延迟500ms注册。

3. 经验总结
Android Framework提供的很多binder接口都是有返回值的,app在使用这些binder接口的时候,要充分利用这些返回值,不能简单的认为,调用了框架接口,就一定能成功。但是google的某些接口也是存在问题的,我们不要迷信google这种大公司一定不会有问题,要用审视的眼光去看待问题,从源码出发,源码是不会骗人的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值