2016-08-02 5 views
2

私はAndroid開発の新機能です。私が追加すべき詳細があれば教えてください。OneDrive SDKを使用してAsyncTaskでファイルをダウンロードすると、NetworkOnMainThreadExceptionがスローされます

私が知る限り、AsyncTaskはワーカースレッドを使用しているため、NetworkOnMainThreadExceptionが発生しません。私が間違ったことは何ですか?ありがとう。

私はOneDrive's Explorerの例の構造を暗示しています。 IOneDriveClientのインスタンスを含むbaseApplication extends Applicationを作成しました。

/** 
* 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でリクエストの設定を呼び出す必要はありません。クライアント上で.get()を呼び出すときに問題が発生するため、AsyncTasksuccess()コールバックに入れたい場合があります。これはブロッキング操作であり、現在のスレッド上でアクションを実行します。この場合、そのスレッドはそのスレッドから呼び出されるsuccessというmainThreadです。

解決策:どの部分が非同期であり、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

ありがとう。 "new Thread"でdownloadTaskを実行しようとしましたが、 "NetworkOnMainThreadException"はまだ発生します。 – Chiu

関連する問題