Как получить доступ к уже запущенному контексту приложения из службы адаптера синхронизации в Android? - PullRequest
5 голосов
/ 05 ноября 2011

У меня есть приложение, состоящее из нескольких действий, и я использую контекст приложения (заданный из класса приложения, и я сделал его постоянным) для обмена данными и объектами между всеми действиями.Я использую класс приложений вместо фоновой службы по нескольким веским причинам, которые я не буду здесь вдаваться.

Недавно я добавил в приложение специальный адаптер синхронизации контактов.Он в одной упаковке, в одном и том же APK.Итак, я настроил его для доступа к контексту приложения, как и все остальное в моем приложении, чтобы дать ему доступ ко всем общим данным и объектам.Однако, хотя он работает (в основном), он создает новый экземпляр контекста приложения.Таким образом, в основном запущено 2 отдельных экземпляра моего приложения, и данные между ними не передаются.

Я думаю, что проблема в том, что мой Applicattion никогда не запускает службу синхронизации, ОС запускает.Все остальные мои действия либо запускаются приложением, либо основное действие обращается к контексту приложения при его запуске, а затем контекст приложения контролирует все остальное.Есть ли способ предоставить службе синхронизации доступ к существующему контексту приложения вместо создания его нового экземпляра?

Вот базовая структура моего приложения:

Приложение

package com.mycomany.myapp;    
public class MyApp extends Application{
    ...
}

Activity1

package com.mycomany.myapp;
public class MyActivity1 extends Activity{
    MyApp a;

    @Override
    public void onCreate(Bundle savedInstanceState){
        a = (MyApp) getApplicationContext();
        ...
    }
}

SyncAdapterService

package com.mycomany.myapp;
public class SyncAdapterService extends Service {
    private static SyncAdapterImpl sSyncAdapter = null;
    private static final Object sSyncAdapterLock = new Object();
    private static ContentResolver mContentResolver = null;
    private static MyApp a;

    public SyncAdapterService() {
        super();
    }

    private static class SyncAdapterImpl extends AbstractThreadedSyncAdapter {
        private Context mContext;

        public SyncAdapterImpl(Context context) {
            super(context, true);
            mContext = context;
        }

        @Override
        public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
            try {
                SyncAdapterService.performSync(mContext, account, extras, authority, provider, syncResult);
            } catch (OperationCanceledException e) {}
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        synchronized (sSyncAdapterLock) {
            if(a == null){
                a = (MyApp) getApplicationContext();
            }
            if (sSyncAdapter == null) {
                sSyncAdapter = new SyncAdapterImpl(getApplicationContext());
            }
        }
    }

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

    private static void performSync(Context context, Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult)
            throws OperationCanceledException {
...
    }
}

Ответы [ 3 ]

7 голосов
/ 16 ноября 2013

Вы скопировали и вставили этот тренинг для SyncAdapter http://developer.android.com/training/sync-adapters/creating-sync-adapter.html?

В конце есть фрагмент XML:

    <service
            android:name="com.example.android.datasync.SyncService"
            android:exported="true"
            android:process=":sync">
        <intent-filter>com.example.android.datasync.provider
            <action android:name="android.content.SyncAdapter"/>
        </intent-filter>
        <meta-data android:name="android.content.SyncAdapter"
                android:resource="@xml/syncadapter" />
    </service>

Атрибут android: process = ": sync" означает, что вы создаете отдельный процесс синхронизации. Удалите его, и все готово.

1 голос
/ 31 декабря 2011

У вас все еще есть эта проблема?Если служба объявлена ​​в вашем файле манифеста без указания другого процесса android:, разве она не должна выполняться в процессе по умолчанию, определенном вашей задачей?Разве вы не можете в этом случае просто использовать getApplicationContext, чтобы получить то, что вам нужно?Мой адаптер синхронизации реализован таким образом, и он работает

1 голос
/ 05 ноября 2011

Возможно, вы захотите изучить привязку службы к контексту вашего приложения.Таким образом, если контекст вашего приложения не существует, служба не будет существовать, так как она работает в том же процессе (что и приложение).См. bindSerivce ()

Если ваша служба удаленная, попробуйте использовать обратные вызовы

...