2015-06-17 2 views
1

Вот мой onResume звонок в MainActivity:Android Broadcast Receiver SharedPreferences пустой на 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); 
    } 
} 

Вот мой onResume в классе, который простирается BroadcastReceiver:

@Override 
    public void onReceive(Context context, Intent intent){ 
     try{ 
      String referrerString = intent.getStringExtra("referrer"); 

      if(null != referrerString){ 
       String referrer = URLEncoder.encode(referrerString, "UTF-8"); 
       context.getSharedPreferences(INSTALL_PREFERENCE, Context.MODE_PRIVATE).edit().putString(REFERRAL_KEY, referrer).commit(); 
      } 

     } 
     catch (Exception e){ 
      //don't handle exceptions for now 
     } 
    } 

Вопрос заключается в том, что, когда я вызовите MainActivity, открыв приложение, мое приложение не вернет referrer при первом открытии. Есть ли причина, по которой SharedPreferences не будет хранить мой referrer при открытии первого приложения? Я хочу передать referrer на первый открытый, а не второй.

ответ

0

on resume() будет выполнен перед приемником вещания и, следовательно, в первый раз, когда вы можете получить нулевое значение или значение по умолчанию для реферера и в более поздний период времени, если вы снова откроете действие, которое может получить правильное значение, потому что onReceive() выполнил бы к этому времени.

Если ваше приложение имеет экран настроек настроек, который фактически инициализирует настройки только после его открытия, вам может потребоваться инициализировать все настройки со значениями по умолчанию перед использованием. Это может быть причиной того, что иногда, если вы открываете приложение, вы получаете правильные значения, потому что вы можете открыть экран настроек.

+0

Есть ли способ убедиться, что я могу получить это в первом приложении? – locoboy

+0

Вы знаете, где это поведение документировано? – locoboy

+0

Это не документировано, а это мой личный опыт. – 7383

1

Вот один из способов исправить это. Внесите в свою деятельность интерфейс OnSharedPreferenceChangeListener, который вызовет обратный вызов onSharedPreferenceChanged(), когда будет изменено любое значение в файле SharedPreference.

Если время правильное, и вы получаете значение в 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 
       //....... 
      } 
     } 
    } 
} 
+0

Не знаете, как это фактически изменит что-либо с момента запуска приложения, и основное действие будет запускать все обратные вызовы без сохранения общих привилегий. – locoboy

+0

@locoboy вы не можете отсрочить жизненный цикл Activity (и не хотите), поэтому лучше всего дать пользователю отзыв о том, что вы чего-то ждали, а затем получить значение как можно быстрее, затем обновите пользовательский интерфейс после получения значения. –

+0

Проблема не в том, что я хочу дать отзыв пользователей, проблема в том, что «referrer» - это то, что мне нужно в «MainActivity» при первом запуске приложения. Я также не хочу ждать его и заставлять остальную часть приложения зависать. – locoboy

0

ссылающиеся широковещательный слегка отправляются после основного компонента вашего приложения запускается. Поэтому вы должны уведомлять свою деятельность после получения трансляции.
Одно простое решение было бы использовать 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(); 
} 

Если вам нужно полностью fonctional образец кода/приложения, проверить мой OpenSource проект GitHub.