Exceptions during the "SyncAdapter" execution

682 views Asked by At

I have got problem implementing a Syncadapter which has a dummy account and a dummmy accountauthenticator.

My accountauthenticator,CNAuthenticator:

public class CNAuthenticator extends AbstractAccountAuthenticator {

public CNAuthenticator(Context context) {
    super(context);
}

@Override
public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
    return null;
}

@Override
public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) throws NetworkErrorException {
    return null;
}

@Override
public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, Bundle options) throws NetworkErrorException {
    return null;
}

@Override
public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException {
    return null;
}

@Override
public String getAuthTokenLabel(String authTokenType) {
    return null;
}

@Override
public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException {
    return null;
}

@Override
public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, String[] features) throws NetworkErrorException {
    return null;
}
}

My authentication service, CNAuthenticatorService:

public class CNAuthenticatorService extends Service {
private CNAuthenticator cnAuthenticator;
public CNAuthenticatorService() {
}

@Override
public void onCreate() {
    super.onCreate();
    cnAuthenticator= new CNAuthenticator(this);
}

@Override
public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    return cnAuthenticator.getIBinder();
}
}

My syncadapter,CNSyncAdapter:

public class CNSyncAdapter extends AbstractThreadedSyncAdapter {
private static final String LOG_TAG = "CNSyncAdapter";

public CNSyncAdapter(Context context, boolean autoInitialize) {
    super(context, autoInitialize);
}

@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
    Log.d(LOG_TAG, "onPerformSync Called.");
}

public static Account getSyncAccount(Context context) {
    // Get an instance of the Android account manager
    AccountManager accountManager =(AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);

    // Create the account type and default account
    Account newAccount = new Account(context.getString(R.string.app_name), context.getString(R.string.sync_account_type));

    // If the password doesn't exist, the account doesn't exist
    if ( null == accountManager.getPassword(newAccount) ) {

    /*
     * Add the account and account type, no password or user data
     * If successful, return the Account object, otherwise report an error.
     */
        if (!accountManager.addAccountExplicitly(newAccount, null, null)) {
            return null;
        }
        /*
         * If you don't set android:syncable="true" in
         * in your <provider> element in the manifest,
         * then call ContentResolver.setIsSyncable(account, AUTHORITY, 1)
         * here.
         */

    }
    return newAccount;


}


public static void syncImmediately(Context context) {
    Bundle bundle = new Bundle();
    bundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
    bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
    ContentResolver.requestSync(getSyncAccount(context),
            context.getString(R.string.content_authority), bundle);
}

public static void initializeSyncAdapter(Context context) {
    getSyncAccount(context);
}


}

My service for syncadapter,CNSyncService:

public class CNSyncService extends Service {
private static final Object sSyncAdapterLock = new Object();
private static final String LOG_TAG ="CNSyncService" ;
private static CNSyncAdapter cnSyncAdapter = null;

public CNSyncService() {
    Log.d(LOG_TAG, "onCreate");
    synchronized (sSyncAdapterLock) {
        if (cnSyncAdapter==null)
            cnSyncAdapter = new CNSyncAdapter(getBaseContext(),true);
    }
}


@Override
public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    return cnSyncAdapter.getSyncAdapterBinder();
}
}

I am getting a exception when I call CNSyncAdapter.syncImmediately(getActivity()) in one of my fragments.

My logcat,

06-22 19:48:35.080  27790-28417/com.mobileapplicationsclub.cashnote.app W/dalvikvm﹕ threadid=17: thread exiting with uncaught exception (group=0x41e0c2b8)
06-22 19:48:35.120  27790-28417/com.mobileapplicationsclub.cashnote.app E/AndroidRuntime﹕ FATAL EXCEPTION: SyncAdapterThread-1
java.lang.NullPointerException
        at android.content.AbstractThreadedSyncAdapter$SyncThread.run(AbstractThreadedSyncAdapter.java:252)

Plz help.I don't know what is causing it.

Its weird but when I change from getBaseContext() to getApplicationContext() I am getting a different error.

My logcat when the change is made:

06-22 20:21:00.630  29104-29104/com.mobileapplicationsclub.cashnote.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to instantiate service com.mobileapplicationsclub.cashnote.app.CNSyncService: java.lang.NullPointerException
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:2406)
        at android.app.ActivityThread.access$1700(ActivityThread.java:140)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1319)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:174)
        at android.app.ActivityThread.main(ActivityThread.java:4952)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
        at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.NullPointerException
        at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:101)
        at com.mobileapplicationsclub.cashnote.app.CNSyncService.<init>(CNSyncService.java:17)
        at java.lang.Class.newInstanceImpl(Native Method)
        at java.lang.Class.newInstance(Class.java:1319)
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:2403)

CNSyncService.java:17 is cnSyncAdapter = new CNSyncAdapter(getApplicationContext(),true)

1

There are 1 answers

0
Simas On BEST ANSWER

You should use the Service constructor. Android does that implicitly when you call startService. You can instead use the onCreate callback method to implement your custom code:

public class CNSyncService extends Service {
    private static final Object sSyncAdapterLock = new Object();
    private static final String LOG_TAG ="CNSyncService" ;
    private static CNSyncAdapter cnSyncAdapter = null;

    @Override
    public void onCreate() {
        super.onCreate();

        Log.d(LOG_TAG, "onCreate");
        synchronized (sSyncAdapterLock) {
            if (cnSyncAdapter==null)
                cnSyncAdapter = new CNSyncAdapter(getBaseContext(),true);
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return cnSyncAdapter.getSyncAdapterBinder();
    }
}