Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/208.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android广播接收器SharedReferences在初始活动时为空';简历_Android_Referrer - Fatal编程技术网

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();
}