1. ホーム
  2. アンドロイド

NetworkOnMainThreadException

2022-01-24 05:10:22

<スパン Web上の関連情報を個人的にまとめたものです。

<スパン <スパン アンドロイド 4.0では、ネットワークにアクセスするための旧コードを修正する必要があります

<スパン

エントリーアクティビティーのonCreateに追加する

  1. // 詳細はStrictModeのドキュメントをご覧ください。  
  2.         StrictMode.setThreadPolicy()を実行します。 新規  StrictMode.ThreadPolicy.Builder()    
  3.                 .detectDiskReads()    
  4.                 .detectDiskWrites()    
  5.                 .detectNetwork()    // あるいは、検出可能なすべての問題のための .detectAll()  
  6.                 .penaltyLog()    
  7.                 .build())のようになります。    
  8.         StrictMode.setVmPolicy( 新規  StrictMode.VmPolicy.Builder()    
  9.                 .detectLeakedSqlLiteObjects()    
  10.                 .detectLeakedClosableObjects()    
  11.                 .penaltyLog()    
  12.                 .penaltyDeath()    
  13.                 .build())のようになります。   

public void onCreate(Bundle savedInstanceState) { の中に、上記と同様に

  1. サプレスリント(SuppressLint ( "NewApi" )  

また、上部には

  1. <スパン インポート  android.os.StrictMode;  

今回実験しているプログラムは、「HeadFirst Android Development」の第3章にある「NASA Daily Image」というプログラムです。

コードを追加すると、ネットワークにアクセスできるようになり、rssがそれを読み込んで画像と対応する情報にアクセスし、表示することができます。



<スパン

<スパン Android.os.NetworkOnMainThreadException

この例外は、メインスレッドでネットワークにアクセスする際の例外を意味していると思われます。Androidは4.0以前のバージョンではメインスレッドでネットワークにアクセスすることをサポートしていましたが、4.0以降この部分は最適化され、ネットワークにアクセスするコードはメインスレッドで書けなくなりました。

<スパン
では、どうすれば正常に動作するようになるのでしょうか?こちらをご覧ください。
<スパン

例 WebからUrlアドレスを取得する。 

  1. url = AuthUtil.getAuthorizationURL()。  
  2. もし  (url ==)  ヌル ) {  
  3.     Toast.makeText(WebViewActivity. これ R.string.auth_url_empty,  3000 ).show()を実行します。  
  4. }  

メインスレッドに直接書き込むと、2.xではまだ動きますが、4.0以降ではエラーが発生します。


<スパン を追加するなどの情報も、ネット上にたくさんあります。

  1. // 詳細はStrictModeのドキュメントをご覧ください。
  2. StrictMode.setThreadPolicy()を実行します。 新規  StrictMode.ThreadPolicy.Builder()  
  3.         .detectDiskReads()  
  4.         .detectDiskWrites()  
  5.         .detectNetwork()    // あるいは、検出可能なすべての問題のための .detectAll()
  6.         .penaltyLog()  
  7.         .build())のようになります。  
  8. StrictMode.setVmPolicy( 新規  StrictMode.VmPolicy.Builder()  
  9.         .detectLeakedSqlLiteObjects()  
  10.         .detectLeakedClosableObjects()  
  11.         .penaltyLog()  
  12.         .penaltyDeath()  
  13.         .build())のようになります。  

<スパン しかし

.detectLeakedClosableObjects() は、次のようなエラーを報告します。 


つまり、このメソッドは使われていないのですが、ソースコードを見ると、そのメソッドがpublicであることがわかります


  1. /**
  2.              * {@link java.io.
  3.              * 終了方法が明示されているオブジェクトを確定する。
  4.              * 閉じていないこと。
  5. <スパン              *
  6.              * <p>このようなオブジェクトは、常に明示的に閉じて
  7. <スパン              * 不要なリソース漏れを防ぐことができます。
  8. <スパン              */
  9. 公開  Builder detectLeakedClosableObjects() { {...  
  10. 戻る  enable(DETECT_VM_CLOSABLE_LEAKS)を使用します。  
  11.             }  

<スパン これにはちょっと戸惑いましたね、まだ上級者ではないので。どうなっているのかわからない。

そこで、2つ目の方法として、マルチスレッドで非同期的にデータを読み込む方法を使うことにします。

コードはこのようになります。

main関数で空のメッセージを送信します。

  1. <スパン 新規  スレッド(){  
  2. オーバーライド
  3. 公開 ボイド  run() {  
  4. // TODO 自動生成されるメソッドスタブ
  5. スーパー .run()を実行します。  
  6.                 url = AuthUtil.getAuthorizationURL()。  
  7. もし  (url ==)  ヌル ) {  
  8.                     Toast.makeText(WebViewActivity. これ R.string.auth_url_empty,  3000 ).show()を実行します。  
  9.                 }  
  10.                 ハンドラ.sendEmptyMessage() 0 );  
  11.             }  
  12.         }.start();  

undefined undefined