Android android.os.NetworkOnMainThreadException 解决方案Demo

来源:互联网 发布:thinkphp与php的区别 编辑:程序博客网 时间:2024/06/08 11:51

初学者在开发中,主要是4.0以后的开发中,经常会遇到android.os.NetworkOnMainThreadException的异常。

产生主线程异常的原因就是,google开发者,在4.0之后吧版本中,为了考虑各方面的性能,包括提高用户体验,避免产生ANR,所以在主线程中不允许再进行网络请求。

所以我们的解决办法就是:在主线程中开启子线程进行网络请求等耗时的操作。

下面这个Demo:就是在主线程中开启一个子线程,能够完美的解决MainThreadException。主要用到了Handler机制。


下面开始学习:

该项目就是从网络上获取一张图片,然后显示在ImageView。

效果图:

代码很简单:

布局文件activity_main:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <TextView        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:gravity="center"        android:text="网络获取图片实例" />    <ImageView        android:id="@+id/imageView"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_weight="20" />    <EditText        android:text="http://m3.biz.itc.cn/pic/new/n/54/56/Img5435654_n.jpg"        android:id="@+id/editText"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:hint="请输入您的网络地址"        android:singleLine="true" />    <Button        android:id="@+id/button"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="点 击 获 取" /></LinearLayout>

代码:

MainActivity:

package com.mynetdemohuoquimg;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.ImageView;import android.widget.Toast;public class MainActivity extends Activity implements OnClickListener {private ImageView imageView;private EditText editText;private Button button;private final int SUCCESS = 0;private final int FAILURE = 1;/** * 在主线程中初始化一个Handler */private Handler handler = new Handler() {public void handleMessage(Message msg) {switch (msg.what) {// 获取成功case SUCCESS:imageView.setImageBitmap((Bitmap) msg.obj);break;// 获取失败case FAILURE:Toast.makeText(MainActivity.this, "获取图片失败", Toast.LENGTH_SHORT).show();break;default:break;}};};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init();}private void init() {imageView = (ImageView) findViewById(R.id.imageView);editText = (EditText) findViewById(R.id.editText);button = (Button) findViewById(R.id.button);button.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.button:// 点击按钮,开启新的子线程进行网络请求。new Thread() {final String path = editText.getText().toString();public void run() {try {URL url = new URL(path);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setConnectTimeout(5000);conn.setRequestMethod("GET");int code = conn.getResponseCode();if (code == 200) {InputStream is = conn.getInputStream();Bitmap bm = BitmapFactory.decodeStream(is);/** * 网络请求完毕,获取位图后,因为不能再子线程中更新UI, * 所以需由Handler发送消息到主线程中,由主线程更新UI。 */Message msg = new Message();msg.what = SUCCESS;// 获取成功时,发送消息为SUCCESS,即0;msg.obj = bm;handler.sendMessage(msg);} else {Message msg = new Message();msg.what = FAILURE;// 获取失败时,发送消息FAILURE,即1;handler.sendMessage(msg);}} catch (Exception e) {Message msg = new Message();msg.what = FAILURE;// 获取失败时,发送消息FAILURE,即1;handler.sendMessage(msg);e.printStackTrace();}};}.start();break;default:break;}}}

源代码下载:

点击下载源码



0 0
原创粉丝点击