2016-08-02 118 views
2

我對Android開發相當陌生。請讓我知道我應該添加更多細節。使用OneDrive SDK下載AsyncTask文件NetworkOnMainThreadException

據我所知,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(); 
    } 
} 

而在我的片段中,我創建了一個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) 
+1

可能重複[如何解決android.os.NetworkOnMainThreadException?](http://stackoverflow.com/questions/6343166/how-to-fix-android-os-networkonmainthreadexception) –

回答

2

它看起來像OneDriveClient是爲你辦理異步。

因此,您不需要調用AsyncTask中基本上請求的設置。您可能需要在success()回撥中放入AsyncTask,因爲問題出在您在客戶端上撥打.get()時發生。這是一個阻塞操作,它將在當前線程上執行此操作。在這種情況下,該線程是從該線程調用的主線程success

解決方案:瞭解哪些部件是異步的,並將它們從mainThread中移出。簡化代碼,以便您可以瞭解哪些部分失敗。

使用斷點和/或日誌來查看您在不同位置處的線程。

+1

謝謝!在success()回調中使用AsyncTask。 – Chiu

0

你的onPostExecute方法在哪裏?

這是一篇好文章對你:當你的應用程序嘗試網絡在主線程中運行How to fix android.os.NetworkOnMainThreadException?

NetworkOnMainThreadException被拋出。 嘗試使用runOnUiThread:

runOnUiThread(new Runnable() { 
       public void run() { 
       // call your async task. 
      } 
     }); 
0

在UIThread,你不能運行像訪問network.So耗時的操作,你應該在其他線程中運行它。你可以試試這個:

DownloadTask downloadTask = new DownloadTask(); 
new Thread(new Runnable() { 
     @Override 
     public void run() { 
      downloadTask.execute();  
     } 
    }).start(); 
+0

謝謝。只是嘗試在「新線程」中執行downloadTask,但仍然發生「NetworkOnMainThreadException」。 – Chiu