Closed isabsent closed 1 month ago
It seems your MSAAuthenticator caches the activity in which authenticator was created and does not release it after authentication process is finalized. It leads to memory leak (thanks to Leak Canary): Leak Canary log:
D/LeakCanary: * com.example.activity.OneDriveActivity has leaked: D/LeakCanary: * GC ROOT static com.example.cloud.Clouds.ONE_DRIVE D/LeakCanary: * references com.example.cloud.Clouds.cloud D/LeakCanary: * references com.example.cloud.OneDriveCloud.service D/LeakCanary: * references com.onedrive.sdk.extensions.OneDriveClient.mAuthenticator D/LeakCanary: * references com.example.activity.OneDriveActivity$1.this$0 (anonymous subclass of com.onedrive.sdk.authentication.MSAAuthenticator) D/LeakCanary: * leaks com.example.activity.OneDriveActivity instance
Activity used to authenticate a user is:
public class OneDriveActivity extends CloudActivity{ public static String ACCESS_KEY_NAME = "ACCESS_KEY_ONEDRIVE", ACCESS_SECRET_NAME = "ACCESS_SECRET_ONEDRIVE"; private static String CLIENT_ID = "****************", OAUTH_2 = "oauth2:"; private static String[] SCOPES_ARRAY = new String[] {"onedrive.readwrite", "onedrive.appfolder", "wl.offline_access"}; private final AtomicReference<IOneDriveClient> mClient = new AtomicReference<>(); private Button mSubmit; private IClientConfig createConfig() { final MSAAuthenticator msaAuthenticator = new MSAAuthenticator() { @Override public String getClientId() { return CLIENT_ID; } @Override public String[] getScopes() { return SCOPES_ARRAY; } }; return DefaultClientConfig.createWithAuthenticator(msaAuthenticator); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_onedrive); mSubmit = (Button) findViewById(R.id.auth_button); mSubmit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mSubmit.setEnabled(false); final ICallback<Void> serviceCreatedCallback = new DefaultCallback<Void>(OneDriveActivity.this) { @Override public void success(final Void result) { mSubmit.setEnabled(true); storeAuth(mClient.get().getAuthenticator().getAccountInfo().getAccessToken(), OneDriveActivity.this); ONE_DRIVE.getOneDrive().setService(mClient.get()); setResult(RESULT_OK); finish(); } }; try { IOneDriveClient service = getOneDriveClient(); mSubmit.setEnabled(true); storeAuth(service.getAuthenticator().getAccountInfo().getAccessToken(), OneDriveActivity.this); ONE_DRIVE.getOneDrive().setService(service); setResult(RESULT_OK); finish(); } catch (UnsupportedOperationException ignored) { createOneDriveClient(OneDriveActivity.this, serviceCreatedCallback); } } }); } /** * Get an instance of the service * * @return The Service */ private synchronized IOneDriveClient getOneDriveClient() { if (mClient.get() == null) { throw new UnsupportedOperationException("Unable to generate a new service object"); } return mClient.get(); } /** * Used to setup the Services * @param activity the current activity * @param serviceCreated the callback */ private synchronized void createOneDriveClient(final Activity activity, final ICallback<Void> serviceCreated) { final DefaultCallback<IOneDriveClient> callback = new DefaultCallback<IOneDriveClient>(activity) { @Override public void success(final IOneDriveClient service) { mClient.set(service); serviceCreated.success(null); storeAuth(service.getAuthenticator().getAccountInfo().getAccessToken(), OneDriveActivity.this); ONE_DRIVE.getOneDrive().setService(service); setResult(RESULT_OK); finish(); } @Override public void failure(final ClientException error) { serviceCreated.failure(error); } }; new OneDriveClient .Builder() .fromConfig(createConfig()) .loginAndBuildClient(activity, callback); } private static void storeAuth(String accessToken, Context context) {// Store the OAuth 2 access token, if there is one. if (accessToken != null) { SharedPreferences prefs = FileManagerApplication.getAccountPreferences(context); SharedPreferences.Editor edit = prefs.edit(); edit.putString(ACCESS_KEY_NAME, OAUTH_2); edit.putString(ACCESS_SECRET_NAME, accessToken); edit.commit(); } } }
Thank you for reaching out and for your patience. This SDK is being officially deprecated. See #172 for more information
It seems your MSAAuthenticator caches the activity in which authenticator was created and does not release it after authentication process is finalized. It leads to memory leak (thanks to Leak Canary): Leak Canary log:
Activity used to authenticate a user is: