我已经寻找了至少一个星期的答案,但我仍然不能得到一个直接的答案来解决我的代码问题。我是android开发的新手,所以我假设我还缺少一些更深层次的理解。
我正在开发一个从互联网获取数据的应用程序,所以我试图实现安全措施,以防止应用程序在没有服务的情况下崩溃并破坏用户体验。
我这样做是使用一个onSharedPreferenceChanged。我创建了一个活动,当没有服务时调用(我使用飞机模式测试)和其他原因,如wifi连接和用户选择的仅使用wifi下载数据的首选项。
现在,它工作了几次,然后停止工作,我不知道为什么。我看了Stack OverFLow几天,然后撞到了墙上。当我问我自己的question时,我被引导到这个问题:Different approaches to a Listener。这个问题是不同的,因为这个问题是问为什么我的代码不能工作的具体答案。我也使用了android studio documentation,但它已经过时了。
我不想一直问关于我的代码的问题,因为我在几个活动中使用了SharedPreferences.OnSharedPreferenceChangeListener,所以我只想问,它到底是如何工作的?
我知道它使用了一个经常被垃圾回收的WeakHashMap,但我认为implementing它可以解决这个问题。但是由于某种原因,sharedPreferences的值改变了,但是listener没有被调用。
除了研究这个问题,我还写了一个单独的应用程序来测试onSharedPreferenceChanged是如何工作的,它是如何工作的。不过,这段代码的迭代并不起作用。
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,用户将收到他们的选择正在实施的通知。
这就是为什么我的问题更像是一个概念性的问题,而不是一个“为什么我的代码不工作”的问题。我以为我知道它是怎么工作的,但它不起作用--我一定是错了。
发布于 2019-09-05 00:28:54
所以我想我明白了我在使用SharedPreferences的时候遗漏了什么。我希望SharedPreferences.OnSharedPreferenceChangeListener在每次发生更改时都能捕捉到,但这不是它的工作方式。监听者更善于监听长期变化,例如偏好变化,而不是不断更新的值。
我最终做的是在每个需要监听更改的活动中添加一个BroadcastReceiver,这使得应用程序运行得更加流畅。这是在我记起在Android中读到的时候才意识到的,当活动可以作为独立的程序几乎完全独立地运行时,就会得到最好的结果。
至于SharedPreferences是如何工作的,正如文档所说,它非常简单。开发人员可以将不同类型的数据添加到SharedPreferences的编辑器中,并在另一个应用程序中随意调用它,listener会寻找变化,但它不喜欢不断变化,可以忽略它们。
https://stackoverflow.com/questions/57648355
复制相似问题