我是Android开发的新手。如果有任何更多细节,请告诉我。
据我所知,AsyncTask正在使用工作线程,所以它不应该导致NetworkOnMainThreadException。有什么我做错了吗?感谢。
我已经暗示了OneDrive's Explorer例子的结构。 我创建了一个扩展Application的baseApplication,其中包含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();
}
}
在我的片段中,我创建了一个asynctask类来下载文件。
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;
}
}
用
执行DownloadTask downloadTask = new DownloadTask();
downloadTask.execute();
但是,它在发送GET请求时会导致NetworkOnMainThreadException。
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)
答案 0 :(得分:2)
看起来OneDriveClient
正在为您处理异步。
因此,您不需要在AsyncTask
中调用基本上是请求的设置。您可能希望在AsyncTask
回调中添加success()
,因为问题出在客户端上调用.get()
时。这是一个阻塞操作,它将执行当前线程上的操作。在这种情况下,该线程是从该线程调用的success
的mainThread。
解决方案:了解哪些部分是异步的并将它们移出mainThread。简化您的代码,以便您可以了解哪些部分失败。
使用断点和/或日志查看您在不同位置使用的线程。
答案 1 :(得分:0)
你的onPostExecute方法在哪里?
这是一篇很好的文章:How to fix android.os.NetworkOnMainThreadException?
当您的应用尝试在主线程中进行网络操作时,会引发NetworkOnMainThreadException。 尝试使用runOnUiThread:
runOnUiThread(new Runnable() {
public void run() {
// call your async task.
}
});
答案 2 :(得分:0)
在UIThread中,您无法像访问网络一样运行耗时的操作。因此,您应该在其他线程上运行它。你可以试试这个:
DownloadTask downloadTask = new DownloadTask();
new Thread(new Runnable() {
@Override
public void run() {
downloadTask.execute();
}
}).start();