【问题标题】:Can I write a system property listener in android?我可以在android中编写系统属性监听器吗?
【发布时间】:2016-08-21 13:59:45
【问题描述】:

使用 setprop 命令(通过 adb)在 android 中设置系统属性后,有没有办法在我自己的服务中监听此更改?

我尝试使用 SystemProperties.addChangeCallback 并没有收到通知。有什么我错过的吗?

【问题讨论】:

    标签: android listener system-properties


    【解决方案1】:

    您可以在您的服务中创建一个方法,该方法应该获取任何 Systemproperty,并且该方法应该调用 Looper.loop();这样该循环将不时轮询 SystemProperty 这个实现可能不是优化的方式,但它在 Android 4.4.2 中使用,你可以在这里看到http://androidxref.com/4.4.2_r2/xref/frameworks/base/services/java/com/android/server/SystemServer.java 您可以在上面的链接中看到:

        boolean disableStorage = SystemProperties.getBoolean("config.disable_storage", false);
        boolean disableMedia = SystemProperties.getBoolean("config.disable_media", false);
        boolean disableBluetooth = SystemProperties.getBoolean("config.disable_bluetooth", false);
        boolean disableTelephony = SystemProperties.getBoolean("config.disable_telephony", false);
        boolean disableLocation = SystemProperties.getBoolean("config.disable_location", false);
        boolean disableSystemUI = SystemProperties.getBoolean("config.disable_systemui", false);
        boolean disableNonCoreServices = SystemProperties.getBoolean("config.disable_noncore", false);
        boolean disableNetwork = SystemProperties.getBoolean("config.disable_network", false);
    

    在 Looper.loop() 的帮助下,在 initAndLoop() 方法中检查这些布尔变量;在这里,您甚至可以在单个 SystemProperty 中通知您的其他组件。

    另一种方法是创建静态回调并调用任何 SystemProperty 中的任何更改,请在此处查看主分支的 SystemService 代码:https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/os/SystemService.java

    您可以在上面的链接中看到以下代码在做什么:

    private static Object sPropertyLock = new Object();
    
    static {
        SystemProperties.addChangeCallback(new Runnable() {
            @Override
            public void run() {
                synchronized (sPropertyLock) {
                    sPropertyLock.notifyAll();
                }
            }
        });
    }
    
    /**
     * Wait until given service has entered specific state.
     */
    public static void waitForState(String service, State state, long timeoutMillis)
            throws TimeoutException {
        final long endMillis = SystemClock.elapsedRealtime() + timeoutMillis;
        while (true) {
            synchronized (sPropertyLock) {
                final State currentState = getState(service);
                if (state.equals(currentState)) {
                    return;
                }
    
                if (SystemClock.elapsedRealtime() >= endMillis) {
                    throw new TimeoutException("Service " + service + " currently " + currentState
                            + "; waited " + timeoutMillis + "ms for " + state);
                }
    
                try {
                    sPropertyLock.wait(timeoutMillis);
                } catch (InterruptedException e) {
                }
            }
        }
    }
    
    /**
     * Wait until any of given services enters {@link State#STOPPED}.
     */
    public static void waitForAnyStopped(String... services)  {
        while (true) {
            synchronized (sPropertyLock) {
                for (String service : services) {
                    if (State.STOPPED.equals(getState(service))) {
                        return;
                    }
                }
    
                try {
                    sPropertyLock.wait();
                } catch (InterruptedException e) {
                }
            }
        }
    }
    

    此信息来自 Shridutt Kothari。查看thisgoogle 发布的关于监听单个 SystemProperty 更改的帖子

    【讨论】:

    • 我已经阅读了这篇文章以及其他几篇帖子以及link 显示的代码,但没有收到任何回调。我使用反射来获取 SystemProperties 类并调用 addChangeCallback()。我曾尝试在我的服务中使用 Binder 进行交易。我知道当我切换飞行模式时 gsm.* 系统属性会发生变化,所以我希望至少得到一个回调。然而,我还没有管理它。那么有更完整的答案吗?
    • @DavidWhite 你有没有设法找到如何做到这一点?
    • 不,我没有。对不起
    猜你喜欢
    • 2016-06-22
    • 1970-01-01
    • 2011-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-28
    • 1970-01-01
    • 2012-06-10
    相关资源
    最近更新 更多