前言:继上篇,上篇中实现了AsyncTask异步加载图片,在文章最后,我们抛出了个问题:“如果想在doInBackground()中更新UI怎么办”这篇文章就是解决这个问题的,本篇程序建立在上篇基础之上,在看本篇之前,请先移步上篇《AsnyncTask与handler(一)——AsyncTask异步处理》
相关文章:《AsnyncTask与handler(一)——AsyncTask异步处理》
有关hander.postDelayed()的一个重要问题是:《销毁activity时注意关闭线程》,不然可能会造成activity已经销毁,而postDelayed的线程过段时间又运行,产生错误!!
Handler一般有两种用途:1)执行计划任务,你可以再预定的实现执行某些任务,可以模拟定时器。2)线程间通信。在Android的应用启动时,会创建一个主线程,主线程会创建一个消息队列来处理各种消息。当你创建子线程时,你可以再你的子线程中拿到父线程中创建的Handler对象,就可以通过该对象向父线程的消息队列发送消息了。由于Android要求在UI线程中更新界面,因此,可以通过该方法在其它线程中更新界面。
使用handler机制的方法:
1、新建一个handler类来处理主线程中的UI更新问题
private class MyHandler extends Handler{ @Override public void handleMessage(Message msg) {//处理消息 switch (msg.what) { case 1: String str=(String) msg.obj; Toast.makeText(getApplicationContext(),str, Toast.LENGTH_SHORT).show(); break; default: break; } } }
2、定义变量与赋值
定义一个变量Handler m_mainHandler;然后在OnCreate()函数中对其初始化:m_mainHandler=new MyHandler();
3、发送消息
Message msg=new Message(); msg.what=1; msg.obj="传回图片了"; m_mainHandler.sendMessage(msg); //发送消息更新UI
在上篇的基础上,在doInBackground()中利用handler发送消息,使其发出Toast消息提示---“传回照片了”。
总体效果为:
XML没变,JAVA代码如下:
package com.example.try_asynctask_handler; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.List; import android.os.AsyncTask; import android.os.Bundle; import android.os.Debug; import android.os.Handler; import android.os.Message; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.Log; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.Toast; public class MainActivity extends Activity { private ImageView image = null; private Button show; private ProgressBar progressBar = null; private int number = 0; List<String> imageUrl = null; Handler m_mainHandler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); m_mainHandler=new MyHandler(); progressBar = (ProgressBar) findViewById(R.id.processBar); image = (ImageView) findViewById(R.id.image); show = (Button) findViewById(R.id.show); show.setOnClickListener(new showButtonListener()); imageUrl = new ArrayList<String>(); // 图片地址List imageUrl.add("http://image.tianjimedia.com/uploadImages/2011/266/AIO90AV2508S.jpg"); imageUrl.add("http://image.tianjimedia.com/uploadImages/2012/090/063N2L5N2HID.jpg"); imageUrl.add("http://comic.sinaimg.cn/2011/0824/U5237P1157DT20110824161051.jpg"); imageUrl.add("http://image.tianjimedia.com/uploadImages/2012/090/1429QO6389U8.jpg"); imageUrl.add("http://new.aliyiyao.com/UpFiles/Image/2011/01/13/nc_129393721364387442.jpg"); } public class showButtonListener implements OnClickListener { @Override public void onClick(View v) { number++; MyAsyncTask myAsyncTask = new MyAsyncTask(getApplicationContext()); myAsyncTask.execute(imageUrl.get(number % 5)); } } class MyAsyncTask extends AsyncTask<String, Integer, Bitmap> { // 可变长的输入参数,与AsyncTask.exucute()对应 public MyAsyncTask(Context context) { progressBar.setVisibility(View.VISIBLE); image.setVisibility(View.GONE); } @Override protected Bitmap doInBackground(String... params) { Bitmap bitmap = null; try { //根据URL取得图片并返回 URL url = new URL(params[0]); URLConnection conn = url.openConnection(); conn.connect(); InputStream inputStream = conn.getInputStream(); bitmap = BitmapFactory.decodeStream(inputStream); Message msg=new Message(); msg.what=1; msg.obj="传回图片了"; m_mainHandler.sendMessage(msg); //发送消息更新UI // Toast.makeText(getApplicationContext(), "传回图片了", Toast.LENGTH_SHORT).show(); inputStream.close(); } catch (Exception e) { Log.e("msg", e.getMessage()); } return bitmap; } /** * 在doInBackground 执行完成后,onPostExecute方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread. */ @Override protected void onPostExecute(Bitmap bitmap) { progressBar.setVisibility(View.GONE); image.setVisibility(View.VISIBLE); if (bitmap != null) { image.setImageBitmap(bitmap); } else { Toast.makeText(getApplicationContext(), "网络异常", Toast.LENGTH_SHORT).show(); } } /** * 该方法将在执行实际的后台操作前被UI thread调用。这个方法只是做一些准备工作,如在界面上显示一个进度条。 */ @Override protected void onPreExecute() { // 任务启动 Toast.makeText(getApplicationContext(), "任务开始......", Toast.LENGTH_SHORT).show(); } } /** * 新建一个handler类来处理主线程中的UI更新问题 * @author Administrator * */ private class MyHandler extends Handler{ @Override public void handleMessage(Message msg) {//处理消息 switch (msg.what) { case 1: String str=(String) msg.obj; Toast.makeText(getApplicationContext(),str, Toast.LENGTH_SHORT).show(); break; default: break; } } } }
根据上面的使用handler步骤写出以后代码难度不大,这里就不再详细讲解了。
其它
1、handler的另一用法
1、在主线程中创建
m_mianhandler=new Handler();
2、用的时候:
private void promptAlertDialog() { m_mainHandler.post(new Runnable() { public void run() { …… } }); }
这一用法部分相关文章:
《Android--多线程之Handler》:http://www.cnblogs.com/plokmju/p/android_handler.html
源码地址:http://download.csdn.net/detail/harvic880925/7275431 ,不要分,仅供分享
请大家尊重原创者版权,转载请标明出处:http://blog.csdn.net/harvic880925/article/details/24783459,不胜感激!