Android之Looper、Handler、Message、MessageQueue应用篇
简介
上一篇文章介绍了Handler、Message、MessageQueue等Android线程交互方面的内容,Android之理解Looper、Handler、Message、MessageQueue。下面开始实践,学习如何去使用以及应用到程序里面。
实例
在这里使用ListView作为异步下载图片的环境。
1、Handle+Runnable
实现思路是:
1:在UI线程中启动一个线程,让这个线程去下载图片。
2:图片完成下载后发送一个消息去通知UI线程
3:UI线程获取到消息后,更新UI。
package com.example.handlerloadiage; import java.io.IOException; import java.net.URL; import android.app.Activity; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; public class Handler_Runnable_Mode extends Activity { private ListView listview; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_handlerimageloader); listview = (ListView) findViewById(R.id.listview); listview.setAdapter(new MyAdapter()); } private class MyAdapter extends BaseAdapter { public MyAdapter() { } @Override public int getCount() { // TODO Auto-generated method stub return 100; } @Override public Object getItem(int position) { // TODO Auto-generated method stub return null; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = LayoutInflater.from(getApplicationContext()) .inflate(R.layout.list_item, null); } final ImageView image = (ImageView) convertView .findViewById(R.id.imageview); final String imageURL = "http://avatar.csdn.net/D/1/4/3_wangjinyu501.jpg"; Handler handler = new Handler(); handler.post(new Runnable() { public void run() { Drawable drawable = null; try { drawable = Drawable.createFromStream( new URL(imageURL).openStream(), "image.jpg"); } catch (IOException e) { Log.d("test", e.getMessage()); } if (drawable == null) { Log.d("test", "null drawable"); } else { Log.d("test", "not null drawable"); } if (drawable == null) { image.setImageResource(R.drawable.ic_launcher); } else { image.setImageDrawable(drawable); } } }); return convertView; } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } }
效果如下:
快速滑动的过程中,还是出现了ANR的现象。
这是因为handler.post(new Runnable()这个方法,并没有开启一个新的线程,他还是在UI主线程中,所以导致出现ANR现象。
2、Handle+Runnable+Message
实现思路:
实现代码:
package com.example.handlerloadiage; import java.io.IOException; import java.net.URL; import android.app.Activity; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; public class Handler_Runnable_Mode extends Activity { private ListView listview; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_handlerimageloader); listview = (ListView) findViewById(R.id.listview); listview.setAdapter(new MyAdapter()); } private class MyAdapter extends BaseAdapter { public MyAdapter() { } @Override public int getCount() { // TODO Auto-generated method stub return 100; } @Override public Object getItem(int position) { // TODO Auto-generated method stub return null; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = LayoutInflater.from(getApplicationContext()) .inflate(R.layout.list_item, null); } final ImageView image = (ImageView) convertView .findViewById(R.id.imageview); final String imageURL = "http://avatar.csdn.net/D/1/4/3_wangjinyu501.jpg"; final Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); Drawable d=(Drawable) msg.obj; if (d == null) { image.setImageResource(R.drawable.ic_launcher); } else { image.setImageDrawable(d); } } }; handler.post(new Runnable() { public void run() { Drawable drawable = null; try { drawable = Drawable.createFromStream( new URL(imageURL).openStream(), "image.jpg"); Message message=handler.obtainMessage(); message.obj=drawable; handler.sendMessage(message); } catch (IOException e) { Log.d("test", e.getMessage()); } if (drawable == null) { Log.d("test", "null drawable"); } else { Log.d("test", "not null drawable"); } } }); return convertView; } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } }
也是会出现ANR的现象,原因和之前一样。