NetworkOnMainThreadException

时间:2011-03-01 04:57:10

标签: android networking asynchronous android-asynctask networkonmainthread

我刚刚在官方文档中找到了NetworkOnMainThreadException

并且想知道模拟器是否正在抛出这个。我一直在测试我的应用程序,据我所知,所有网络都是主线程(使用Roboguice RoboAsyncTask),但你永远不知道是否有人没有转义。

我也在使用StrictMode并且没有看到任何东西。

  1. 我的代码是干净的还是不会在模拟器上抛出?

  2. 我们应该如何为生产中的这种情况做好准备?

  3. 宽限期或其他什么? 或者现在已经过去了;-) ??

5 个答案:

答案 0 :(得分:12)

如文档所述,使用蜂窝网络,您无法在其主线程上执行网络操作。因此,您必须使用handler或asynctask。没有其他方法可以做到这一点。

在这里你可以找到2个用土耳其语写的关于网络操作的例子。也许他们会帮忙。

答案 1 :(得分:5)

我已经测试了这个,它实际上也发生在模拟器上。如果您计划将其应用到3.0平板电脑以及更高版本,请确保至少在模拟器上测试您的应用。

答案 2 :(得分:3)

在main方法中执行某些网络操作时会发生

NetworkOnMainThreadException;我的意思是Oncreate()。您可以使用AsyncTask来解决此问题。或者你可以使用

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

onCreate()方法内。

答案 3 :(得分:1)

如果你在3.0上运行,我无能为力;因为Strict模式默认打开;但它高于一定,那么这可能会有所帮助

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

在创建HTTP连接之前包含此内容;然后它工作

答案 4 :(得分:1)

从Honeycomb SDK(3)开始,Google将不再允许网络请求(HTTP,Socket)和其他相关操作直接在主线程类中,实际上,不应该在UI线程中直接进行网络操作,阻塞UI,用户体验不好!即使谷歌不被禁止,一般情况下,我们也不会这样做〜! 所以,也就是说,在Honeycomb SDK(3)版本中,你也可以继续在主线程中这样做,超过3个,它将无法工作。

1.使用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.使用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);
    }
}

3.使用StrictMode

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