android 异步handle

将new Handle 放入线程中,会报错Can't create handler inside thread that has not called Looper.prepare()

private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
// Looper.prepare();
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Toast.makeText(MainActivity.this, msg.obj.toString(), Toast.LENGTH_SHORT).show();
str = msg.obj.toString();
}
};
// Looper.loop();
}
}).start();
}

//网络获取数据
public void getData(View view) {
new Thread(new Runnable() {
@Override
public void run() {
try {
URL url = new URL("http://t.weather.sojson.com/api/weather/city/101030100");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
if (conn.getResponseCode() == 200) {
InputStream in = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String s = reader.readLine();
// Bitmap bitmap1= BitmapFactory.decodeStream(in);
//异步大师要我们按规范做事
Message message = handler.obtainMessage();
message.obj = s;
handler.sendMessage(message);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}

一、为什么呢?

因为toast的实现需要在activity的主线程才能正常工作,所以传统的非主线程不能使toast显示在actvity上,通过Handler可以使自定义线程运行于Ui主线程。

因为Handler对象与其调用者在同一线程中,如果在Handler中设置了延时操作(比如访问网络数据),则调用线程也会堵塞。每个Handler对象都会绑定一个Looper对象,每个Looper对象对应一个消息队列(MessageQueue)。如果在创建Handler时不指定与其绑定的Looper对象,系统默认会将当前线程的Looper绑定到该Handler上。

在主线程中,可以直接使用new Handler()创建Handler对象,其将自动与主线程的Looper对象绑定;在非主线程中直接这样创建Handler则会报错,因为Android系统默认情况下非主线程中没有开启Looper,而Handler对象必须绑定Looper对象。

因为主线程自带Looper机制,所有我们不用创建Looper了。

这种情况下,则有两种方法可以解决此问题:

二、解决方法是什么呢?

方法一:将上面代码中的注释去掉

Looper.prepare();//1、初始化Looper

handler = new Handler() {//2、绑定handler到当前线程实例的Looper对象
    @Override
public void handleMessage(Message msg) {//3、定义处理消息的方法
super.handleMessage(msg);
Toast.makeText(MainActivity.this, msg.obj.toString(), Toast.LENGTH_SHORT).show();
str = msg.obj.toString();
}
};

 Looper.loop();//4、启动消息循环

方法二:

handler = new Handler(Looper.getMainLooper())

猜你喜欢

转载自www.cnblogs.com/zzsgz/p/9824665.html