首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >onSharedPreferncesChanged方法是如何工作的?

onSharedPreferncesChanged方法是如何工作的?
EN

Stack Overflow用户
提问于 2019-08-26 01:46:24
回答 1查看 60关注 0票数 0

我已经寻找了至少一个星期的答案,但我仍然不能得到一个直接的答案来解决我的代码问题。我是android开发的新手,所以我假设我还缺少一些更深层次的理解。

我正在开发一个从互联网获取数据的应用程序,所以我试图实现安全措施,以防止应用程序在没有服务的情况下崩溃并破坏用户体验。

我这样做是使用一个onSharedPreferenceChanged。我创建了一个活动,当没有服务时调用(我使用飞机模式测试)和其他原因,如wifi连接和用户选择的仅使用wifi下载数据的首选项。

现在,它工作了几次,然后停止工作,我不知道为什么。我看了Stack OverFLow几天,然后撞到了墙上。当我问我自己的question时,我被引导到这个问题:Different approaches to a Listener。这个问题是不同的,因为这个问题是问为什么我的代码不能工作的具体答案。我也使用了android studio documentation,但它已经过时了。

我不想一直问关于我的代码的问题,因为我在几个活动中使用了SharedPreferences.OnSharedPreferenceChangeListener,所以我只想问,它到底是如何工作的?

我知道它使用了一个经常被垃圾回收的WeakHashMap,但我认为implementing它可以解决这个问题。但是由于某种原因,sharedPreferences的值改变了,但是listener没有被调用。

除了研究这个问题,我还写了一个单独的应用程序来测试onSharedPreferenceChanged是如何工作的,它是如何工作的。不过,这段代码的迭代并不起作用。

代码语言:javascript
复制
public class MainActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener{
static final String TAG = "MainActivity";
public static final String SHARED_PREFS = "sharedPrefs";
public static final String WIFI_CONNECTION = "WiFi";
public static final String CELLULAR_CONNECTION = "Cellular";
public static final String CONNECTION = "Connection";

private NetworkCheck networkCheck;
SharedPreferences sharedPreferences;


boolean wifi;
boolean cellular;
boolean connected;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    wifiT = findViewById(R.id.wifi);
    cellularT = findViewById(R.id.mobile);
    connectedT = findViewById(R.id.connected);




    sharedPreferences = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
    wifi = sharedPreferences.getBoolean(WIFI_CONNECTION, false);
    cellular = sharedPreferences.getBoolean(CELLULAR_CONNECTION, false);
    connected = sharedPreferences.getBoolean(CONNECTION, false);

 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    switch (key){
        case CONNECTION:
            connected = sharedPreferences.getBoolean(CONNECTION, false);
            Log.i(TAG, "sharedStuff In: connection: " + wifi + " cellular: "
                    + cellular + " connected: " + connected);
            setStuff();
            break;
        case WIFI_CONNECTION:
            wifi = sharedPreferences.getBoolean(WIFI_CONNECTION, false);
            Log.i(TAG, "sharedStuff In: wifi: " + wifi + " cellular: " +
                    cellular + " connected: " + connected);
            setStuff();

            break;
        case CELLULAR_CONNECTION:
            cellular = sharedPreferences.getBoolean(CELLULAR_CONNECTION, false);
            Log.i(TAG, "sharedStuff In: cellular: " + wifi + " cellular: " +
                    cellular + " connected: " + connected);
            setStuff();
            break;
        default:
            connected = sharedPreferences.getBoolean(CONNECTION, false);
            Log.i(TAG, "sharedStuff In: default: " + wifi + " cellular: " +
                    cellular + " connected: " + connected);
    }
    Log.i(TAG, "sharedStuff Out: listener: " + wifi + " cellular: " +
            cellular + " connected: " + connected);

}

 void setStuff() {
    if(wifi)
        wifiT.setText("WIfi Is Connected");
    else
        wifiT.setText("WIfi Is Not Connected");
    if(cellular)
        cellularT.setText("Cellular Is Connected");
    else
        cellularT.setText("Cellular Is Not Connected");
    if (connected)
        connectedT.setText("Network Is Connected");
    else
        connectedT.setText("Network Is Not Connected");
}
 @Override
protected void onStart() {
    super.onStart();
    IntentFilter filter = new IntentFilter();
    filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
    filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
    this.registerReceiver(networkCheck, filter);
    PreferenceManager.getDefaultSharedPreferences(this)
            .registerOnSharedPreferenceChangeListener(this);

}



@Override
protected void onStop() {
    super.onStop();
    if (networkCheck != null) {
        this.unregisterReceiver(networkCheck);
        PreferenceManager.getDefaultSharedPreferences(this)
                .unregisterOnSharedPreferenceChangeListener(this);
    }
}

首选项是从另一个使用‘`ConnectivityManager’的活动加载的。我已经对它进行了广泛的测试,到目前为止,它每次都有效。

我想让我的应用程序“看到”用户手机上的服务发生了变化,并采取相应的行动。例如,我打开了应用程序,如果没有服务,它将不会从谷歌和facebook请求数据,直到有服务,如果没有wifi服务,并且用户明确只想使用wifi,用户将收到他们的选择正在实施的通知。

这就是为什么我的问题更像是一个概念性的问题,而不是一个“为什么我的代码不工作”的问题。我以为我知道它是怎么工作的,但它不起作用--我一定是错了。

EN

回答 1

Stack Overflow用户

发布于 2019-09-05 00:28:54

所以我想我明白了我在使用SharedPreferences的时候遗漏了什么。我希望SharedPreferences.OnSharedPreferenceChangeListener在每次发生更改时都能捕捉到,但这不是它的工作方式。监听者更善于监听长期变化,例如偏好变化,而不是不断更新的值。

我最终做的是在每个需要监听更改的活动中添加一个BroadcastReceiver,这使得应用程序运行得更加流畅。这是在我记起在Android中读到的时候才意识到的,当活动可以作为独立的程序几乎完全独立地运行时,就会得到最好的结果。

至于SharedPreferences是如何工作的,正如文档所说,它非常简单。开发人员可以将不同类型的数据添加到SharedPreferences的编辑器中,并在另一个应用程序中随意调用它,listener会寻找变化,但它不喜欢不断变化,可以忽略它们。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57648355

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档