Android 异步加载解决方案
来源:互联网 发布:js实现的简单的小特效 编辑:程序博客网 时间:2024/06/01 09:27
1、背景:
Android应用在5s内无响应的话会导致ANR(Application Not Response),
这就要求开发者必须遵循两条法则:
1.1、不能阻塞UI线程,
1.2、确保只在UI线程中访问Android UI工具包。
于是,开启子线程进行异步处理的技术方案应运而生。
2、解决方法:
(1)、AsyncTask简介
AsyncTask的特点是任务在主线程之外运行,而回调方法是在主线程中执行;
public class AsyncTastActivity extends Activity { private List<String> urlList; private ImageAdapter listItemAdapter; private ArrayList<HashMap<String, Object>> listItem; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); urlList = new ArrayList<String>(); urlList.add("http://www.baidu.com/img/baidu_sylogo1.gif"); urlList.add("http://y2.ifengimg.com/2012/06/24/23063562.gif"); urlList.add("http://himg2.huanqiu.com/statics/images/index/logo.png"); listItem = new ArrayList<HashMap<String, Object>>(); listItemAdapter = new ImageAdapter(this, listItem); ListView listView = (ListView) this.findViewById(R.id.listView1); listView.setAdapter(listItemAdapter); AsyncTask<List<String>, Integer, Hashtable<String, SoftReference<Drawable>>> task = new AsyncTask<List<String>, Integer, Hashtable<String, SoftReference<Drawable>>>() { @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected Hashtable<String, SoftReference<Drawable>> doInBackground( List<String>... params) { Hashtable<String, SoftReference<Drawable>> table = new Hashtable<String, SoftReference<Drawable>>(); List<String> imageUriList = params[0]; for (String urlStr : imageUriList) { try { URL url = new URL(urlStr); Drawable drawable = Drawable.createFromStream( url.openStream(), "src"); table.put(urlStr, new SoftReference<Drawable>(drawable)); } catch (Exception e) { e.printStackTrace(); } } return table; } @Override protected void onPostExecute( Hashtable<String, SoftReference<Drawable>> result) { super.onPostExecute(result); Collection<SoftReference<Drawable>> col = result.values(); for (SoftReference<Drawable> ref : col) { HashMap<String, Object> map = new HashMap<String, Object>(); map.put("ItemImage", ref.get()); listItem.add(map); } listItemAdapter.notifyDataSetChanged(); } }; task.execute(urlList); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; }}
(2)、采用Thread + Handler + Message
Handler简介 Handler为Android提供了一种异步消息处理机制,它包含两个队列,一个是线程列队,另一个是消息列队。使用post方法将线 程对象添加到线程队列中,使用sendMessage(Message message)将消息放入消息队列中。当向消息队列中发送消息后就立 即返回,而从消息队列中读取消息对象时会阻塞,继而回调Handler中public void handleMessage(Message msg)方法。因此 在创建Handler时应该使用匿名内部类重写该方法。如果想要这个流程一直执行的话,可以再run方法内部执行postDelay或者 post方法,再将该线程对象添加到消息队列中重复执行。想要停止线程,调用Handler对象的removeCallbacks(Runnable r)从 线程队列中移除线程对象,使线程停止执行。
public class ThreadHandlerActivity extends Activity { private List<String> urlList; private ImageAdapter listItemAdapter; private LinkedList<HashMap<String, Object>> listItem; private Handler handler; private ExecutorService executorService = Executors.newFixedThreadPool(10); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); urlList = new ArrayList<String>(); urlList.add("http://www.baidu.com/img/baidu_sylogo1.gif"); urlList.add("http://y2.ifengimg.com/2012/06/24/23063562.gif"); urlList.add("http://himg2.huanqiu.com/statics/images/index/logo.png"); listItem = new LinkedList<HashMap<String, Object>>(); listItemAdapter = new ImageAdapter(this, listItem); ListView listView = (ListView) this.findViewById(R.id.listView1); listView.setAdapter(listItemAdapter); handler = new Handler(){ @Override public void handleMessage(Message msg) { HashMap<String, Object> map = (HashMap<String, Object>) msg.obj; listItem.add(map); listItemAdapter.notifyDataSetChanged(); } }; for (final String urlStr : urlList) { executorService.submit(new Runnable() { @Override public void run() { try { URL url = new URL(urlStr); Drawable drawable = Drawable.createFromStream( url.openStream(), "src"); HashMap<String, Object> table = new HashMap<String, Object>(); table.put("ItemImage", drawable); Message msg = new Message(); msg.obj = table; msg.setTarget(handler); handler.sendMessage(msg); } catch (Exception e) { e.printStackTrace(); } } }); } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; }}
(3)、采用Thread + Handler + post方法
使用post方法将Runnable对象放到Handler的线程队列中,该Runnable的执行其实并未单独开启线程,而是仍然在当前Activity的UI线程中执行,Handler只是调用了Runnable对象的run方法。
public class ThreadHandlerPostActivity extends Activity { private List<String> urlList; private ImageAdapter listItemAdapter; private LinkedList<HashMap<String, Object>> listItem; private Handler handler = new Handler(); private ExecutorService executorService = Executors.newFixedThreadPool(10); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); urlList = new ArrayList<String>(); urlList.add("http://www.baidu.com/img/baidu_sylogo1.gif"); urlList.add("http://y2.ifengimg.com/2012/06/24/23063562.gif"); urlList.add("http://himg2.huanqiu.com/statics/images/index/logo.png"); listItem = new LinkedList<HashMap<String, Object>>(); listItemAdapter = new ImageAdapter(this, listItem); ListView listView = (ListView) this.findViewById(R.id.listView1); listView.setAdapter(listItemAdapter); for (final String urlStr : urlList) { executorService.submit(new Runnable() { @Override public void run() { try { URL url = new URL(urlStr); Drawable drawable = Drawable.createFromStream( url.openStream(), "src"); final HashMap<String, Object> table = new HashMap<String, Object>(); table.put("ItemImage", drawable); handler.post(new Runnable(){ @Override public void run() { listItem.add(table); listItemAdapter.notifyDataSetChanged(); } }); } catch (Exception e) { e.printStackTrace(); } } }); } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; }}
- Android 异步加载解决方案
- Android 异步加载解决方案
- Android 异步加载解决方案
- Android 异步加载解决方案
- 【Android】异步加载解决方案
- Android异步加载解决方案
- Android 异步加载解决方案
- Android 异步加载解决方案
- Android 异步加载解决方案
- Android 异步加载解决方案
- Android 异步加载解决方案
- Android 异步加载解决方案
- Android 异步加载解决方案
- Android 异步加载解决方案
- Android 异步加载解决方案
- android 异步加载解决方案 AsyncTask
- 【异步加载】Android 网络数据异步加载解决方案
- android的异步加载图片的解决方案
- linux权限篇【二】
- iOS 获取当前点击的cell相对于self.view的位置
- svm中的数学和算法
- JavaSE Collection
- Android Bluetooth蓝牙开发(二)
- Android 异步加载解决方案
- android 添加ios点击edittext之外关闭键盘功能
- linux工具篇
- 基本语法i++ ++i
- 避免Android开发中的ANR
- linux后台运行和开机启动篇【一】
- 买二手车注意事项
- Web开发人员常犯的10个错误
- matlab将向量或矩阵复制升维