You should know by looking at the name that it is an exception generated by a network request in MainThread
Let's take a look at the official website's explanation:
Class Overview
The exception that is thrown when an application attempts to perform a networking operation on its main thread.
This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it's heavily discouraged. See the document Designing for Responsiveness.
Also see StrictMode
.
http://developer.android.com/intl/zh-cn/reference/android/os/NetworkOnMainThreadException.html
Explain, starting from Honeycomb SDK (3.0), google no longer allows network requests (HTTP, Socket) and other related operations to be directly in the Main Thread class. In fact, it should not be done in the first place. Performing network operations directly on the UI thread will block UI and user experience are pretty bad! Even if Google doesn't ban it, we won't do it under normal circumstances~
So, that is to say, in versions below Honeycomb SDK (3.0), you can continue to do this in the Main Thread, but in versions above 3.0, it will not work, it is recommended
1. The time-consuming operations related to the network are placed in a sub-thread, and then the Handler message mechanism is used to communicate with the main thread.
- publicvoid onCreate(Bundle savedInstanceState) {
- super .onCreate (savedInstanceState);
- this.setContentView(R.layout.test);
- // Open a sub thread, perform network operations, wait for a return result, and use the handler to notify the UI
- new Thread(networkTask).start();
- }
- Handler handler = new Handler () {
- @Override
- publicvoid handleMessage(Message msg) {
- super.handleMessage(msg);
- Bundle data = msg.getData();
- String val = data.getString("value");
- Log.i( "mylog" , "The request result is -->" + val);
- // EVERYTHING
- // UI interface update and other related operations
- }
- };
- /**
- * Sub-threads related to network operations
- */
- Runnable networkTask = new Runnable() {
- @Override
- publicvoid run() {
- // EVERYTHING
- // Perform http request. Network request related operations here
- Message msg = new Message();
- Bundle data = new Bundle();
- data.putString( "value" , "request result" );
- msg.setData(data);
- handler.sendMessage(msg);
- }
- };
2. Use asynchronous mechanisms such as: asynctask, this is a simple example of loading network pictures
- class DownImage extends AsyncTask {
- private ImageView imageView;
- public DownImage(ImageView imageView) {
- this.imageView = imageView;
- }
- @Override
- protected Bitmap doInBackground(String... params) {
- String url = params[0];
- Bitmap bitmap = null;
- try {
- //加载一个网络图片
- InputStream is = new URL(url).openStream();
- bitmap = BitmapFactory.decodeStream(is);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return bitmap;
- }
- @Override
- protected void onPostExecute(Bitmap result) {
- imageView.setImageBitmap(result);
- }
- }
3,直接在main Thread 进行网络操作的方法,网上给出的,我没有具体测试:
在发起Http请求的Activity里面的onCreate函数里面添加如下代码:
- StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
- .detectDiskReads().detectDiskWrites().detectNetwork()
- .penaltyLog().build());
- StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
- .detectLeakedSqlLiteObjects().detectLeakedClosableObjects()
- .penaltyLog().penaltyDeath().build());
Remember, if a handler is declared in the Main Thread, the Runnable (Thread) posted by this handler and the processed message are all in the current mian thread, not a child thread.