I'm fairly new to Android development. Please let me know should there be any more detail I should add.
As far as I know, AsyncTask is using a worker thread, so it shouldn't cause NetworkOnMainThreadException. Is there anything I did wrong? Thanks.
I have intimated the structure of OneDrive's Explorer example. I created an baseApplication extending Application, which includes an instance for IOneDriveClient.
/**
* Base application
*/
public class OneDriveBaseApplication extends Application {
public static final String Log_Tag = "MyDebug";
/**
* The service instance
*/
private final AtomicReference<IOneDriveClient> mClient = new AtomicReference<>();
/**
* Create the client configuration
* @return the newly created configuration
*/
private IClientConfig createConfig() {
final MSAAuthenticator msaAuthenticator = new MSAAuthenticator() {
@Override
public String getClientId() {
SharedPreferences onedrivePref = getApplicationContext().getSharedPreferences(getString(R.string.onedrive_pref_key), Context.MODE_PRIVATE);
String msa_client_id = onedrivePref.getString(getString(R.string.onedrive_pref_app_key), "");
Log.v(Log_Tag, msa_client_id);
return msa_client_id;
}
@Override
public String[] getScopes() {
return new String[]{"onedrive.appfolder offline_access"};
}
};
final IClientConfig config = DefaultClientConfig.createWithAuthenticator(msaAuthenticator);
config.getLogger().setLoggingLevel(LoggerLevel.Debug);
return config;
}
/**
* Used to setup the Services
*
* @param activity the current activity
* @param serviceCreated the callback
*/
synchronized void createOneDriveClient(final Activity activity, final ICallback<Void> serviceCreated) {
final DefaultCallback<IOneDriveClient> callback = new DefaultCallback<IOneDriveClient>(activity) {
@Override
public void success(final IOneDriveClient result) {
mClient.set(result);
serviceCreated.success(null);
}
@Override
public void failure(final ClientException error) {
serviceCreated.failure(error);
}
};
new OneDriveClient
.Builder()
.fromConfig(createConfig())
.loginAndBuildClient(activity, callback);
}
/**
* Get an instance of the service
*
* @return The Service
*/
synchronized IOneDriveClient getOneDriveClient() {
if (mClient.get() == null) {
throw new UnsupportedOperationException("Unable to generate a new service object");
}
return mClient.get();
}
}
And in my fragment, I created an asynctask class to download files.
private class DownloadTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
final OneDriveBaseApplication app = (OneDriveBaseApplication)getActivity().getApplication();
try {
app.getOneDriveClient()
.getDrive()
.getSpecial("approot")
.getChildren()
.buildRequest()
.get(new DefaultCallback<IItemCollectionPage>(getActivity()) {
@Override
public void success(final IItemCollectionPage result) {
Log.v(OneDriveBaseApplication.Log_Tag, "get children success");
if (result != null) {
for (final Item childItem : result.getCurrentPage()) {
try {
final String itemId = childItem.id;
final String itemName = childItem.name;
byte[] buffer = new byte[1024];
int len = 0;
Log.v(OneDriveBaseApplication.Log_Tag, "name " + itemName + " id " + itemId);
final File firDownloadDir = new File(Environment.getExternalStorageDirectory() + File.separator + "downloaded_files");
firDownloadDir.mkdir();
final File file = new File(firDownloadDir, itemName);
Log.v(OneDriveBaseApplication.Log_Tag, "File path " + file.getPath());
FileOutputStream out = new FileOutputStream(file);
Log.v(OneDriveBaseApplication.Log_Tag, "FileOutputStream Established");
/* Get the file from OneDrive*/
Log.v(OneDriveBaseApplication.Log_Tag, "To get the file from OneDrive");
InputStream in = app.getOneDriveClient()
.getDrive()
.getItems(itemId)
.getContent()
.buildRequest()
.get();
Log.v(OneDriveBaseApplication.Log_Tag, "Get the file from OneDrive succesfully");
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
Log.v(OneDriveBaseApplication.Log_Tag, "Write successfully: " + childItem.name);
} catch (FileNotFoundException ex) {
Log.v(OneDriveBaseApplication.Log_Tag, "File not found when downloading: " + childItem.name);
} catch (IOException ex) {
Log.v(OneDriveBaseApplication.Log_Tag, "IOException when writing/reading: " + childItem.name);
}
}
}
}
@Override
public void failure(ClientException ex) {
Log.v(OneDriveBaseApplication.Log_Tag, "ClientException");
}
});
} catch (UnsupportedOperationException ex) {
Log.v(OneDriveBaseApplication.Log_Tag, "UnsupportedOperationException");
} catch (Error error) {
Log.v(OneDriveBaseApplication.Log_Tag, "Error for whatsoever");
}
return null;
}
}
And execute it with
DownloadTask downloadTask = new DownloadTask();
downloadTask.execute();
However, it results a NetworkOnMainThreadException when sending a GET request.
202: Starting to send request, URL https://api.onedrive.com/v1.0/drive/items/AB76E7297xxxxxxx!110/content
206: Request Method GET
312: Error during http request
com.onedrive.sdk.core.ClientException: Error during http request
at com.onedrive.sdk.http.DefaultHttpProvider.sendRequestInternal(DefaultHttpProvider.java:309)
at com.onedrive.sdk.http.DefaultHttpProvider.send(DefaultHttpProvider.java:165)
at com.onedrive.sdk.http.BaseStreamRequest.send(BaseStreamRequest.java:76)
at com.onedrive.sdk.generated.BaseItemStreamRequest.get(BaseItemStreamRequest.java:60)
at tw.com.www.onedrivedemo.PlaceholderFragment$DownloadTask$1.success(PlaceholderFragment.java:159)
at tw.com.www.onedrivedemo.PlaceholderFragment$DownloadTask$1.success(PlaceholderFragment.java:133)
at com.onedrive.sdk.concurrency.DefaultExecutors$1.run(DefaultExecutors.java:88)
at com.onedrive.sdk.concurrency.SynchronousExecutor$1.onPostExecute(SynchronousExecutor.java:54)
at com.onedrive.sdk.concurrency.SynchronousExecutor$1.onPostExecute(SynchronousExecutor.java:46)
at android.os.AsyncTask.finish(AsyncTask.java:660)
at android.os.AsyncTask.-wrap1(AsyncTask.java)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:677)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303)
at com.android.org.conscrypt.Platform.blockGuardOnNetwork(Platform.java:300)
at com.android.org.conscrypt.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:808)
at com.android.okhttp.okio.Okio$1.write(Okio.java:76)
at com.android.okhttp.okio.AsyncTimeout$1.write(AsyncTimeout.java:155)
at com.android.okhttp.okio.RealBufferedSink.flush(RealBufferedSink.java:221)
at com.android.okhttp.internal.http.HttpConnection.flush(HttpConnection.java:141)
at com.android.okhttp.internal.http.HttpTransport.finishRequest(HttpTransport.java:52)
at com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:904)
at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:782)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:463)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:405)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:521)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java)
at com.onedrive.sdk.http.UrlConnection.getResponseCode(UrlConnection.java:100)
at com.onedrive.sdk.http.DefaultHttpProvider.sendRequestInternal(DefaultHttpProvider.java:245)
at com.onedrive.sdk.http.DefaultHttpProvider.send(DefaultHttpProvider.java:165)
at com.onedrive.sdk.http.BaseStreamRequest.send(BaseStreamRequest.java:76)
at com.onedrive.sdk.generated.BaseItemStreamRequest.get(BaseItemStreamRequest.java:60)
at tw.com.www.onedrivedemo.PlaceholderFragment$DownloadTask$1.success(PlaceholderFragment.java:159)
at tw.com.www.onedrivedemo.PlaceholderFragment$DownloadTask$1.success(PlaceholderFragment.java:133)
at com.onedrive.sdk.concurrency.DefaultExecutors$1.run(DefaultExecutors.java:88)
at com.onedrive.sdk.concurrency.SynchronousExecutor$1.onPostExecute(SynchronousExecutor.java:54)
at com.onedrive.sdk.concurrency.SynchronousExecutor$1.onPostExecute(SynchronousExecutor.java:46)
at android.os.AsyncTask.finish(AsyncTask.java:660)
at android.os.AsyncTask.-wrap1(AsyncTask.java)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:677)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)