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;    }}
0 0
原创粉丝点击