2014-10-16 8 views
13

मैं सफल सिंक के बाद अपने सिंक एडाप्टर में एक साझा पेंशन बदल रहा हूं और कर रहा हूं, लेकिन जब मैं अपनी गतिविधि में वरीयता का उपयोग करता हूं तो मुझे अद्यतन मूल्य नहीं दिख रहा है (बल्कि मैं पुराना मान देख रहा हूं)। मैं क्या गलत कर रहा हूं? विभिन्न संदर्भ?SyncAdapter में साझा किया गया साझा प्राथमिकता गतिविधि में अपडेट नहीं की गई है?

मेरे SyncAdapter जहाँ मैं प्राथमिकता अपडेट:

class SyncAdapter extends AbstractThreadedSyncAdapter { 
    private int PARTICIPANT_ID; 
    private final Context mContext; 
    private final ContentResolver mContentResolver; 

    public SyncAdapter(Context context, boolean autoInitialize) { 
     super(context, autoInitialize); 
     mContext = context; 
     mContentResolver = context.getContentResolver(); 
    } 

    public SyncAdapter(Context context, boolean autoInitialize, boolean allowParallelSyncs) { 
     super(context, autoInitialize, allowParallelSyncs); 
     mContext = context; 
     mContentResolver = context.getContentResolver(); 
    } 

    @Override 
    public void onPerformSync(Account account, Bundle extras, String authority, 
           ContentProviderClient provider, SyncResult syncResult) { 

     final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext); 
     PARTICIPANT_ID = Integer.parseInt(prefs.getString("participant_id", "0")); 

     if (success) { 
      // save and set the new participant id 
      PARTICIPANT_ID = newParticipantId; 
      prefs.edit().putString("participant_id", String.valueOf(newParticipantId)).commit(); 
     } 
    } 
} 

सेवा ApplicationContext साथ SyncAdapter आरंभ:

public class SyncService extends Service { 
    private static final Object sSyncAdapterLock = new Object(); 
    private static SyncAdapter sSyncAdapter = null; 

    @Override 
    public void onCreate() { 
     synchronized (sSyncAdapterLock) { 
      if (sSyncAdapter == null) { 
       sSyncAdapter = new SyncAdapter(getApplicationContext(), false); 
      } 
     } 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     return sSyncAdapter.getSyncAdapterBinder(); 
    } 
} 

आवेदन गतिविधि कि SharedPreference की जाँच करता है के द्वारा कहा जाता है के भीतर एक स्थिर समारोह। यह SyncAdapter में किए गए मान को वापस नहीं करता है, लेकिन पुराना मान। (मेरे SettingsActivity और अन्य गतिविधियां भी पुराने मूल्य का उपयोग करें।):

public static boolean isUserLoggedIn(Context ctx) { 
    final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx); 
    int participantId = Integer.parseInt(prefs.getString("participant_id", "0")); 
    LOGD("dg_Utils", "isUserLoggedIn.participantId: " + participantId);// TODO 
    if (participantId <= 0) { 
     ctx.startActivity(new Intent(ctx, LoginActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)); 
     return false; 
    } 
    return true; 
} 

अद्यतन: मैं नया मान जब मैं पूरी तरह से ऐप्स को बंद (क्षुधा चलने से स्वाइप करें) हो रही है। मेरे पास एक SharePreferenceChangeListener भी है, जिसे वरीयता अद्यतन होने पर निकाल दिया नहीं जाता है।

private final SharedPreferences.OnSharedPreferenceChangeListener mParticipantIDPrefChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() { 
    public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { 
     if (key.equals("participant_id")) { 
      LOGI(TAG, "participant_id has changed, requesting to restart the loader."); 
      mRestartLoader = true; 
     } 
    } 
}; 

@Override 
public void onActivityCreated(Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 

    // subscribe to the participant_id change lister 
    final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); 
    PARTICIPANT_ID = Integer.parseInt(prefs.getString("participant_id", "0")); 
    prefs.registerOnSharedPreferenceChangeListener(mParticipantIDPrefChangeListener); 
} 
+0

कोड है कि आप पोस्ट किया है से ऐसा लगता है कि आप कभी नहीं 'SyncAdapter' पर' startSync() 'फोन जिसका अर्थ है कि' onPerformSync (...) 'विधि निष्पादित और नहीं करता है वरीयता कभी नहीं बदला जाता है। – Titus

+0

@ टिटस कहीं मैं करता हूं और 'onPerformSync()' निश्चित रूप से निष्पादित किया जाता है। यह बाद के syncs में नए मान का भी उपयोग करता है। मुझे पता चला है कि 'सिंक सेवा' एक अलग प्रक्रिया में चल रही है ('')। अब मैं 'ideManager.getDefaultSharedPreferences()' के साथ 'MODE_MULTI_PROCESS' का उपयोग करने का तरीका जानने का प्रयास कर रहा हूं। – matsch

+0

आप 'prefs = mContext.getSharedPreferences ("myAppPrefs", Context.MODE_MULTI_PROCESS) का उपयोग कर सकते हैं;' [यहां] (http://developer.android.com/reference/android/content/Context.html#getSharedPreferences (java.lang .Sring, int)) दस्तावेज है। – Titus

उत्तर

16

ठीक है, मैं इसे बाहर अपने आप @Titus मदद से और कुछ शोध के बाद लगा और साथ में मेरी समस्या के लिए एक समाधान pieced।

कारण है कि एक ही Context की DefaultSharedPreferences अपडेट नहीं होते हैं कि मैं SyncService निर्दिष्ट किया है AndroidManifest.xml में अपनी ही प्रक्रिया में चलाने के लिए (नीचे देखें) है। इसलिए, एंड्रॉइड 2.3 से शुरू होने पर, दूसरी प्रक्रिया को अद्यतन SharedPreferences फ़ाइल तक पहुंचने से अवरुद्ध कर दिया गया है (this answer और Context.MODE_MULTI_PROCESS पर एंड्रॉइड दस्तावेज़ देखें)।

<service 
     android:name=".sync.SyncService" 
     android:exported="true" 
     android:process=":sync" 
     tools:ignore="ExportedService" > 
     <intent-filter> 
      <action android:name="android.content.SyncAdapter" /> 
     </intent-filter> 
     <meta-data 
      android:name="android.content.SyncAdapter" 
      android:resource="@xml/syncadapter" /> 
    </service> 

तो मैं जब SyncAdapter में और मेरे ऐप्लिकेशन के यूआई प्रक्रिया में SharedPreferences दोनों तक पहुँचने MODE_MULTI_PROCESS स्थापित करने के लिए किया था। क्योंकि मैंने पूरे ऐप में PreferenceManager.getDefaultSharedPreferences(Context) बड़े पैमाने पर उपयोग किया है, मैंने एक उपयोगिता विधि लिखी है और इस विधि के साथ PreferenceManager.getDefaultSharedPreferences(Context) की सभी कॉलों को प्रतिस्थापित किया है (नीचे देखें)। प्राथमिकता फ़ाइल का डिफ़ॉल्ट नाम हार्डकोड किया गया है और the Android source code और this answer से लिया गया है।

public static SharedPreferences getDefaultSharedPreferencesMultiProcess(
     Context context) { 
    return context.getSharedPreferences(
      context.getPackageName() + "_preferences", 
      Context.MODE_PRIVATE | Context.MODE_MULTI_PROCESS); 
} 
+0

http://stackoverflow.com/a/6310080/8524 के अनुसार उपर्युक्त कोड को 'SharePreferences' ऑब्जेक्ट को 'SharedPreferences.getDefaultSharedPreferences() 'के रूप में वही' SharePreferences 'ऑब्जेक्ट मिलेगा । – Diederik

+1

हां, यह वही ऑब्जेक्ट प्राप्त करेगा, लेकिन 'Context.MODE_MULTI_PROCESS' संशोधक सेट के साथ। मैं उसी उत्तर से लिंक कर रहा हूं जो आप मेरे पिछले अनुच्छेद में हैं। – matsch

+0

मुझे लगता है कि आपके उत्तर में अच्छा जोड़ा है। मैंने साझा प्राथमिकताओं को प्राप्त करने के लिए किसी भी (जैसे मेरे) ने 'SharedPreferences.getDefaultSharedPreferences() 'का उपयोग किया, और फिर उन्हें एहसास हुआ कि उन्हें बहु प्रक्रिया पहुंच की आवश्यकता है। – Diederik

0

के बाद से SharedPreferences प्रक्रिया-सुरक्षित नहीं हैं, मैं किसी अन्य प्रक्रिया में AbstractThreadedSyncAdapter उपयोग करने के लिए जब तक आप वास्तव में इसकी जरूरत की सिफारिश नहीं होगा।

Why do i need multiple processes in my application?

समाधान

सेवा है कि आप अपने मेनिफ़ेस्ट में घोषित से android:process=":sync" निकालें!

<service 
    android:name=".sync.SyncService" 
    android:exported="true" 
    android:process=":sync" 
    tools:ignore="ExportedService" > 
    <intent-filter> 
     <action android:name="android.content.SyncAdapter" /> 
    </intent-filter> 
    <meta-data 
     android:name="android.content.SyncAdapter" 
     android:resource="@xml/syncadapter" /> 
</service> 
+0

धन्यवाद यह मेरे लिए काम करता है। –

0

मेरे मामले में मैं ब्रॉडकास्ट रिसीवर द्वारा लॉन्च की गई सेवा से साझा किए गए संदर्भों तक पहुंचने का प्रयास कर रहा था।

मैंने इसे प्रबंधित करने के लिए AndroidManifest.xml में घोषणा से android:process=":remote" हटा दिया।

<receiver 
    android:process=":remote" 
    android:name=".Alarm"> 
</receiver> 
संबंधित मुद्दे