web-dev-qa-db-ja.com

NetworkOnMainThreadException

NetworkOnMainThreadException について公式ドキュメントで知りました

エミュレーターがこれをスローしているかどうか疑問に思っていました。私はアプリをかなりテストしており、すべてのネットワークがメインスレッドから外れていることがわかっている限り(Roboguice RoboAsyncTaskを使用)、エスケープされていないかどうかはわかりません。

私もStrictModeを使用しており、何も見ていません。

  1. 私のコードはクリーンですか、それともエミュレータでスローされませんか?

  2. これを本番環境で行うにはどうすればよいでしょうか。

  3. 猶予期間などはどうですか?それとも今は経過していますか;-) ??

27
Manfred Moser

私はこれをテストしましたが、実際にはエミュレータでも発生します。 3.0タブレット以降でアプリを入手する場合は、少なくともエミュレータでアプリをテストすることをおすすめします。

5
Manfred Moser

ハニカムでは、ドキュメントにあるように、メインスレッドでネットワーク操作を実行することはできません。このため、ハンドラーまたは非同期タスクを使用する必要があります。それを行う別の方法はありません。

ここでは、ネットワーク操作についてトルコ語で書かれた2つの例を見つけることができます。多分彼らは助けます。

12
Mustafa Güven

NetworkOnMainThreadExceptionは、いくつかのネットワーク操作がmainメソッド内で実行されるときに発生します。つまりOncreate()です。この問題を解決するには、AsyncTaskを使用できます。またはあなたが使うことができます

_StrictMode.ThreadPolicy mypolicy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
_

onCreate()メソッド内。

3

Honeycomb SDK(3)から、Googleはネットワークリクエスト(HTTP、ソケット)およびその他の関連操作をメインスレッドクラスで直接許可しなくなりました。実際、UIスレッドで直接ネットワーク操作を行うべきではなく、UIをブロックします。ユーザーエクスペリエンスは悪い!グーグルが禁止されていなくても、通常はやらない〜!つまり、Honeycomb SDK(3)バージョンでは、メインスレッドでこれを続行することもできます。3を超えると機能しません。

1.use Handler

ネットワークに関連する時間のかかる操作は子スレッドに配置され、Handlerメッセージングメカニズムを使用してメインスレッドと通信されます

public static final String TAG = "NetWorkException";

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setContentView(R.layout.activity_net_work_exception);
    // Opens a child thread, performs network operations, waits for a return result, and uses handler to notify UI
    new Thread(networkTask).start();
}

Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        // get data from msg and notify UI
        Bundle data = msg.getData();
        String val = data.getString("data");
        Log.i(TAG, "the result-->" + val);
    }
};

/**
 * net work task
 */
Runnable networkTask = new Runnable() {

    @Override
    public void run() {
        // do here, the HTTP request. network requests related operations
        Message msg = new Message();
        Bundle data = new Bundle();
        data.putString("data", "request");
        msg.setData(data);
        handler.sendMessage(msg);
    }
};

2.use AsyncTask

public static final String TAG = "NetWorkException";
private ImageView mImageView;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setContentView(R.layout.activity_net_work_exception);
    mImageView = findViewById(R.id.image_view);
    new DownImage(mImageView).execute();
}


class DownImage extends AsyncTask<String, Integer, Bitmap> {

    private ImageView imageView;

    public DownImage(ImageView imageView) {
        this.imageView = imageView;
    }

    @Override
    protected Bitmap doInBackground(String... params) {
        String url = params[0];
        Bitmap bitmap = null;
        try {
            //load image from internet , http request here
            InputStream is = new URL(url).openStream();
            bitmap = BitmapFactory.decodeStream(is);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bitmap;
    }

    @Override
    protected void onPostExecute(Bitmap result) {
        // nodify UI here
        imageView.setImageBitmap(result);
    }
}

.use StrictMode

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

3.0で実行している場合、私は手伝うことができません。 Strictモードはデフォルトでオンになっているため、しかし、その上に、これは役立つかもしれません

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);

HTTP接続を作成する前にこれを含めてください。その後、動作します

1
Manoj Kumar