博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android线程之 Handler与AsyncTask的应用
阅读量:4297 次
发布时间:2019-05-27

本文共 4719 字,大约阅读时间需要 15 分钟。

做应用程序的开发的时候,我们程序员更多的关心的是线程。

    一个android应用程序开启后,默认开启一个主线程(大部分都和UI相关,所以又叫UI 线程).
在UI线程上面运行的Avtivity组件,Service组件,BroadcastReceiver组件。

    用户操作主线程时,需要注意不允许在UI线程中做耗时的操作。比如:复杂的逻辑计算,休眠,联网,下载数据等都是耗时的操作。如果在UI主线程中做耗时的操作,一旦超过5秒,应用程序抛出异常,会报一个ANR(Application not respond)应用程序无法响应,紧接着退出。

 
ANR错误的演示:
    那么耗时的操作在哪里运行呢?这个时候就需要使用线程了。
这时就不会产生以上的错误了。 如下所示:
把耗时的工作都让子线程去做。
 
注意:Android中的控件只能被UI主线程操作,不能被其他线程操作,否则会有异常的产生】

Handler
     Handler负责在子线程中发送消息。
     Handler负责在主线程中接收消息。
     实现子线程和主线程间的通信。
 
Handler myHandler = new myHandler()
 
运行在主线程中的。主线程收到消息时,主线程通过handleMessage(msg)来接受消息
异步任务类AsyncTask
[1]Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler对象向UI线程发送消息,完成界面的更新,这种方式对整个界面的控制非常精细。
     但是也有缺点,例如代码臃肿,所以为了简化操作,Android 1.5 sdk 提供了一个工具类 AsyncTask(异步任务类),使得创建异步任务变的更加简单。
[2]一个异步任务的执行一般包括以下几个步骤:
     [1]execute(Params... params),执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行。
     [2]onPreExecute(),在execute(Params... params)被调用后立即执行,一般用来在执行后台任务前对UI做一些标记。
     [3]doInBackground(Params... params),在onPreExecute()完成后立即执行,用于执行较为耗时的操作,此方法将接受输入参数和返回计算结果。
        在执行过程中可以调用publicProgress(Progress...values)来更新进度信息。
     [4]onProgressUpdate(Progress... values),在调用publicProgress(Progress... values)时,此方法被执行,直接将进度信息更新到UI组件上。
     [5]onPostExecute(Result result),当后台操作结束时,此方法将会被调用,计算结果将作为参数传递到此方法中,直接将结果显示到UI组件上。
  [3]在使用异步任务时,以下几点需要格外注意:
     [1]异步任务对象必须在UI主线程中创建。
     [2]不要手动调用onPreExcute(),doInBackground(Params... params), onProgressUpdate(Progress... values),onPostExecute(Result result)
     [3]不能再doInBackground(Params... params)中操作UI控件。

     异步任务类是对Handler的一个封装,原理都一样,创建类如下:
相关参数:
参数所代表的意义:
Params: 启动任务时输入的参数类型,如果不需要输入参数,则输入Viod
            该参数只能填写引用数据类型
Progress :后台任务执行的进度类型。

Result : 后台计算结果的类型

例如:  注意要把耗时的操作放在此方法中,注意:传入的参数所在的位置
代码详细解析:
package com.hqyj.handler;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.widget.ProgressBar;import android.widget.TextView;public class Android_22_HandlerActivity extends Activity implements Runnable{    TextView tv;    	ProgressBar pb;//定义进度条    	/** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                tv = (TextView) findViewById(R.id.textView1);        pb = (ProgressBar) findViewById(R.id.progressBar1);//获取进度条的引用                //将耗时的操作放在子线程中        new Thread(this).start();                //计时器        new Thread(new TimeThread()).start();    }    class TimeThread implements Runnable{    	int count;		@Override		public void run() {			// TODO Auto-generated method stub			while(count < 100){				try {					Thread.sleep(1000);					count++;					//向主线程发送消息					Message msg = new Message();//					Bundle bundle = new Bundle();//					bundle.putInt("count", count);//					msg.setData(bundle);					msg.arg1 = count;					myHandler.sendMessage(msg);				} catch (InterruptedException e) {					// TODO Auto-generated catch block					e.printStackTrace();				}			}		}    }    	@Override	public void run() {		// TODO Auto-generated method stub		try {			Thread.sleep(10000); 		} catch (InterruptedException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}	}		//handler对象。负责在子线程中发消息。在主线程中接收并处理消息。实现子线程和主线程的通信。	Handler myHandler = new MyHandler();		class MyHandler extends Handler{				//主线程收到消息时,调用该方法,处理消息。		@Override		public void handleMessage(Message msg) {			// TODO Auto-generated method stub			super.handleMessage(msg);			int count = msg.arg1;			tv.setText(String.valueOf(count));						pb.setProgress(count);		}	}}
Asyctask:
package com.hqyj.asyctask;import android.os.AsyncTask;import android.widget.TextView;//Params    启动任务时的输入参数类型。注意:该参数只能填写引用数据类型,如果没有参数输入,填写Void//Progress  后台任务执行的进度的类型。//Result    后台计算结果的类型。public class MyAsyncTask extends AsyncTask
{ TextView tv; int count; public MyAsyncTask(TextView tv) { // TODO Auto-generated constructor stub this.tv = tv; } //该方法被子线程调用 //将耗时的操作放在该方法中 @Override protected String doInBackground(Integer... params) { // TODO Auto-generated method stub while(count < params[0]){ //要求系统调用onProgressUpdate方法。 try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } count++; this.publishProgress(count); } return "任务结束"; //返回的是result } //该方法被UI主线程调用 // @Override protected void onProgressUpdate(Integer... values) { // TODO Auto-generated method stub super.onProgressUpdate(values); tv.setText(String.valueOf(values[0])); } //异步任务启动时调用 @Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute(); tv.setText("任务开始"); } //异步任务结束时调用 @Override protected void onPostExecute(String result) { // TODO Auto-generated method stub super.onPostExecute(result); tv.setText(result); }}
你可能感兴趣的文章
通向财务自由之路02_成功的决定因素:你
查看>>
中低频量化交易策略研发01_引言
查看>>
中低频量化交易策略研发06_推进的择时策略
查看>>
史丹·温斯坦称傲牛熊市的秘密
查看>>
期货市场技术分析01_理论基础
查看>>
期货市场技术分析02_趋势的基本概念
查看>>
期货市场技术分析03_主要反转形态
查看>>
期货市场技术分析04_持续形态
查看>>
期货市场技术分析05_交易量和持仓兴趣
查看>>
TB交易开拓者入门教程
查看>>
TB创建公式应用dll失败 请检查用户权限,终极解决方案
查看>>
python绘制k线图(蜡烛图)报错 No module named 'matplotlib.finance
查看>>
talib均线大全
查看>>
期货市场技术分析06_长期图表和商品指数
查看>>
期货市场技术分析07_摆动指数和相反意见理论
查看>>
满屏的指标?删了吧,手把手教你裸 K 交易!
查看>>
不吹不黑 | 聊聊为什么要用99%精度的数据回测
查看>>
X 分钟速成 Python
查看>>
对于模拟交易所引发的思考
查看>>
高频交易的几种策略
查看>>