gpt4 book ai didi

android - 使用 OneDrive SDK 在 AsyncTask 中下载文件抛出 NetworkOnMainThreadException

转载 作者:搜寻专家 更新时间:2023-11-01 09:43:50 30 4
gpt4 key购买 nike

我是 Android 开发的新手。如果我需要添加更多详细信息,请告诉我。

据我所知,AsyncTask 使用的是工作线程,因此它不应导致 NetworkOnMainThreadException。我做错了什么吗?谢谢。

我已经暗示了OneDrive's Explorer的结构例子。我创建了一个扩展应用程序的 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();
}
}

在我的 fragment 中,我创建了一个异步任务类来下载文件。

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)

最佳答案

看起来 OneDriveClient 正在为您处理异步。

因此您不需要在 AsyncTask 中调用本质上是请求设置的内容。您可能希望在 success() 回调中放置一个 AsyncTask,因为问题出在您在客户端调用 .get() 时。这是一个阻塞操作,它将在当前线程上执行操作。在这种情况下,该线程是从该线程调用的 success 的 mainThread。

解决方案:了解哪些部分是异步的并将它们从主线程中移出。简化您的代码,以便您可以了解失败的部分。

使用断点和/或日志来查看您在不同位置处的线程。

关于android - 使用 OneDrive SDK 在 AsyncTask 中下载文件抛出 NetworkOnMainThreadException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38716915/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com