我有一个由多个活动组成的应用程序,我使用应用程序上下文(从应用程序类中使用,并使其持久化)在所有活动之间共享数据和对象。我使用Application Class而不是后台服务有几个很好的理由,我不会在这里讨论。
我最近还在我的应用中添加了自定义联系人同步适配器。它在相同的包下,在同一个APK中。因此,我将其设置为访问应用程序上下文,就像我的应用程序中的其他内容一样,使其可以访问所有共享数据和对象。但是,即使它(大多数情况下)有效,它也会创建一个新的Application Context实例。因此,我的应用程序基本上有两个独立的实例在运行,并且它们之间不共享数据。
我认为问题在于我的应用程序永远不会启动同步服务,操作系统会这样做。我的所有其他活动都是由应用程序启动的,或者主活动在启动时访问Application Context,然后App Context控制其他所有活动。有没有办法让同步服务访问现有的应用程序上下文,而不是创建它的新实例?
以下是我的应用的基本结构:
该应用程序
package com.mycomany.myapp;
public class MyApp extends Application{
...
}
活性1
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 {
...
}
}
答案 0 :(得分:7)
您是否已为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 :(得分:1)
您可能希望将服务绑定到Application上下文。这样,如果您的应用程序上下文不存在,该服务将不存在,因为它在相同的进程(Application的进程)中运行。见bindSerivce()
如果您的服务是远程服务,请尝试使用callbacks
答案 2 :(得分:1)
你还有这个问题吗? 如果在清单文件中声明服务而未指定其他android:进程,那么它是否应该在您的任务定义的默认进程中运行? 在这种情况下你不能只使用getApplicationContext来获得你需要的东西吗? 我有以这种方式实现的同步适配器,它正在工作