Android广播接收器SharedReferences在初始活动时为空';简历
这是我在Android广播接收器SharedReferences在初始活动时为空';简历,android,referrer,Android,Referrer,这是我在main活动中的onResume呼叫: @Override public void onResume() { super.onResume(); SharedPreferences settings = context.getSharedPreferences(INSTALL_PREFERENCE, 0); String referrerString = settings.getString(REFERRAL_KEY, null); Map<Str
main活动中的onResume
呼叫:
@Override
public void onResume() {
super.onResume();
SharedPreferences settings = context.getSharedPreferences(INSTALL_PREFERENCE, 0);
String referrerString = settings.getString(REFERRAL_KEY, null);
Map<String, String> params = new HashMap<~>();
if (referrerString != null){
params.put("referrer", referrerString);
}
}
问题是,当我打开应用程序调用main活动时,我的应用程序在第一次打开时不会返回referer
。是否有理由SharedReferences
不会在第一个打开的应用程序上存储我的Referer
?我想在第一次打开而不是第二次打开时传回参考者。on resume()将在广播接收器之前执行,因此第一次您可能会收到参考者的空值或默认值,如果稍后重新打开活动,您可能会得到正确的值,因为onReceive()到这个时候就会被处决了
如果您的应用程序有任何设置首选项屏幕,而该屏幕实际上只有在打开后才初始化设置,那么在使用它之前,您可能必须使用默认值初始化所有首选项。这可能是因为有时如果打开应用程序,您会得到正确的值,因为您可能已经打开了设置屏幕。以下是一种修复方法。使您的活动实现该接口,当SharedReference文件中的任何值发生更改时,该接口将调用onSharedPreferenceChanged()
回调
如果计时正确,并且您在onResume()
中获得了一个值,只需像在当前代码中一样继续操作即可
如果还没有值,则显示ProgressDialog,并等待BroadcastReceiver填充该值。
一旦BroadcastReceiver修改了该值,请在onSharedPreferenceChanged()
中捕获该值,然后根据需要使用它
以下是解决方案的总体结构:
public class MainActivity extends Activity
implements SharedPreferences.OnSharedPreferenceChangeListener {
SharedPreferences settings;
ProgressDialog dialog;
Map<String, String> params;
String INSTALL_PREFERENCE = "installpref";
String REFERRAL_KEY = "referral";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dialog = new ProgressDialog(this);
params = new HashMap<String, String>();
settings = this.getSharedPreferences(INSTALL_PREFERENCE, 0);
settings.registerOnSharedPreferenceChangeListener(this); //added
}
@Override
public void onResume() {
super.onResume();
String referrerString = settings.getString(REFERRAL_KEY, null);
if (referrerString != null){
params.put("referrer", referrerString);
//call whatever methods need params to have a value
//.......
}
else{
//Show progress dialog and wait for BroadcastReceiver to populate referrer
dialog.setMessage("loading");
dialog.show();
}
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPrefs, String key) {
if (key.equals(REFERRAL_KEY)){
//dismiss dialog if it's showing
if (dialog.isShowing()){
dialog.dismiss();
}
String referrerString = sharedPrefs.getString(REFERRAL_KEY, null);
if (referrerString != null){
params.put("referrer", referrerString);
//call whatever methods need params to have a value
//.......
}
}
}
}
公共类MainActivity扩展活动
实现SharedReferences.OnSharedPreferenceChangeListener{
共享引用设置;
进程对话;
映射参数;
字符串INSTALL\u PREFERENCE=“installpref”;
字符串转诊\ u KEY=“转诊”;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dialog=新建ProgressDialog(此);
params=新的HashMap();
设置=this.getSharedReferences(安装首选项,0);
settings.RegisterOnSharedReferenceChangeListener(此);//已添加
}
@凌驾
恢复时公开作废(){
super.onResume();
String refererString=settings.getString(referer\u键,null);
if(refererString!=null){
参数put(“referer”,refererString);
//调用任何需要参数才能有值的方法
//.......
}
否则{
//显示进度对话框并等待BroadcastReceiver填充推荐人
设置消息(“加载”);
dialog.show();
}
}
@凌驾
已更改共享首选项上的公共void(SharedReferences SharedRefers,字符串键){
if(键等于(参考键)){
//如果对话框正在显示,请将其关闭
if(dialog.isShowing()){
dialog.dismise();
}
String refererString=sharedPrefs.getString(referer\u键,null);
if(refererString!=null){
参数put(“referer”,refererString);
//调用任何需要参数才能有值的方法
//.......
}
}
}
}
在应用程序的主要组件启动后,会稍微发送推荐人广播。因此,您必须在收到广播后立即通知您的活动。
一个简单的解决方案是在接收器和活动之间使用LocalBroadcastManager:
/* BroadcastReceiver */
@Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
String referrer = (String) extras.get(KEY_REFERRER);
// save String to SharedPrefrences
Intent intent = new Intent(ACTION_UPDATE);
intent.putExtra(KEY_REFERRER, referrer);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}
/*****/
/* Activity*/
private final BroadcastReceiver mUpdateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String referrer = intent.getStringExtra(KEY_REFERRER);
}
};
@Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mUpdateReceiver);
super.onPause();
}
@Override
protected void onResume() {
LocalBroadcastManager.getInstance(this).registerReceiver(mUpdateReceiver, new IntentFilter(ReferrerReceiver.ACTION_UPDATE));
super.onResume();
}
如果您需要一个功能完整的示例代码/应用程序,查看我在上的开源项目。有没有办法确保我可以在第一个应用程序上打开它?你知道这种行为记录在哪里吗?它没有记录,而是我的个人经验。你是如何测试的?在应用程序启动时,你应该能够每次读取正确的首选项值。Rest您将知道预期的结果不确定这实际上会如何改变任何东西,因为应用程序将启动,并且主活动将运行所有回调,而不存储共享的pref。@locoboy您不能延迟活动的生命周期(您也不想延迟),所以最好的办法是给用户反馈你在等待什么,然后尽快得到值,然后在得到值后更新UI。问题不是我想给用户反馈,问题在于,在第一次应用程序发布时,referer
是我在main活动中需要的东西。我也不想等待它,让应用程序的其余部分挂起。@locoboy这是此解决方案的全部要点,它使MainActivity能够在不挂起应用程序的情况下尽快获得值。
/* BroadcastReceiver */
@Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
String referrer = (String) extras.get(KEY_REFERRER);
// save String to SharedPrefrences
Intent intent = new Intent(ACTION_UPDATE);
intent.putExtra(KEY_REFERRER, referrer);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}
/*****/
/* Activity*/
private final BroadcastReceiver mUpdateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String referrer = intent.getStringExtra(KEY_REFERRER);
}
};
@Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mUpdateReceiver);
super.onPause();
}
@Override
protected void onResume() {
LocalBroadcastManager.getInstance(this).registerReceiver(mUpdateReceiver, new IntentFilter(ReferrerReceiver.ACTION_UPDATE));
super.onResume();
}