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

[android.os.NetworkOnMainThreadException を解決してください。

2022-01-24 07:12:58

まず引っかかりを感じたので、ブラッシングすることにしました。前作は アンドロイド  2.3 システム . 戻ってきて4.4にフラッシュした。

OK、ここで問題発生です。私の携帯電話で私たちのアプリをテストすると、問題のような例外が発生しました: android.os.NetworkOnMainThreadException

最初にこの例外を見たとき、文字通り「メインスレッド上のネットワーク例外」と書いてありました。それから、この例外を理解するために、まず、以下の公式説明を見てみました。

パブリッククラス

NetworkOnMainThreadException

extends RuntimeException
<テーブル java.lang.Object ? java.lang.Throwable ? java.lang.Exception ? java.lang.RuntimeException ? android.os.NetworkOnMainThreadException

クラス概要


アプリケーションがそのメインスレッドでネットワーク操作を行おうとしたときにスローされる例外です。

これは、Honeycomb SDK 以降をターゲットとするアプリケーションにのみスローされます。以前のSDKバージョンをターゲットとするアプリケーションは、メインイベントループスレッドでネットワーキングを行うことができますが、それは非常に推奨されません。

以下もご参照ください。  StrictMode .


だから、物事はかなり明確です。メインスレッドでネットワーク操作を要求したアプリは、この例外をスローします。アンドロイドは、ネットワーク要求に時間がかかりすぎて、インターフェースが誤って死んでしまうことを防ぐために設計されています。

解決策は2つあり、1つはStrictModeを使用すること、もう1つはスレッドを使用してネットワーク要求を操作することです。

最初の方法:シンプルでブルートフォース、簡単なコード変更で済む(ただし、非常にお勧めできない)。
MainActivity ファイルの setContentView(R.layout.activity_main) の下に以下のコードを追加します。

if (android.os.Build.VERSION.SDK_INT > 9) {
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
}

2つ目の方法は、私が使っている方法であり、私が推奨する方法です。ネットワークリソースを要求するコードを操作するためにThreadを使用します。UIスレッドをブロックすることなく、Runnableの中でHTTPリクエストを行います。

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setContentView(R.layout.main_view);
    new Thread(runnable).start();
}
 
Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        Bundle data = msg.getData();
        String val = data.getString("value");
        Log.i(TAG,"Request result:" + val);
    }
}
 
Runnable runnable = new Runnable(){
    @Override
    public void run() {
        // TODO: http request.
        Message msg = new Message();
        Bundle data = new Bundle();
        data.putString("value","RequestResult");
        msg.setData(data);
        handler.sendMessage(msg);
    }
}

上記は、より一般的なアプローチで、私のコードです。
// HTTP requests cannot be made in the main thread after Android 4.0
            new Thread(new Runnable(){
                @Override
                public void run() {
                    cachedImage = asyncImageLoader.loadDrawable(imageUrl, position);
                    imageView.setImageDrawable(cachedImage);
                }
            }).start();

さて、今日のこのくだりはこれで終わりです。実はアンドロイド開発に関するくだりはこれで全部なのです。他のくだらないことは、以下のコラムをご覧ください。

Android開発のうんちくについては、コラム:"Android開発のうんちくをご覧ください。