Android的多线程编程

使用场景

当我们要进行一些耗时操作(比如发送网络请求),这个时候是不能放在UI线程中执行的,容易造成主线程堵塞。

线程和进程

从操作系统上说,进程是系统资源分配和调度的基本单位,而线程是cpu调度的基本单位,线程是进程的执行单元并且它们共享所在进程的资源。
一个进程至少有一个线程,叫单线程程序,而有多个线程的则是多线程程序,这样的话如果有多个任务,前者只能依次执行,而后者可同时执行。

线程的常见用法

第一种:继承Thread父类并重写run()方法

class MyThread extends Thread{
	@Overirrde
	public void run{
		//some logic
	}
}
new MyThead().start();

第二种:实现Runnable接口

class MyThread implements Runnable{
	@override
	public void run(){
	//some logic
	}
}
new Thread(new MyThread()).start();


//也可以直接使用匿名内部类的方式(常见写法)
new Thread(new Runnable(){
	@override
	public void run(){
	//some logic
	}
}).start();

第三种:实现Callable(可获取返回值)

FutureTask<Integer> futureTask = new FutureTask<>(new MyThread());
class MyThread implements Callable<Integer> {
	 @Override
	 public Integer call() {
	 //some logic
		return 0;
	 }
}
new Thread(futureTask).start();
//使用futureTask.get()获取子线程的返回结果

使用Handler在子线程中更新UI

上述的run()方法中的代码是执行在子线程的,而安卓却是不允许在子线程中对UI操作,但有时候又必须根据子线程的任务执行来更新UI。
对于这个问题,安卓提供了一套异步消息处理机制来解决:

Handler简介

Handler是安卓SDK中处理消息的核心类,其Runnable与一个线程的MessageQueue(消息队列)关联。它既可以处理主线程与子线程的通信,也可以处理子线程与子线程的通信。
下图是Handler的通信机制

在这里插入图片描述
大致的流程是:Handler发送Message对象的消息到MessageQueue,而Looper会一直尝试从消息队列中取出待处理的Message,取出消息就会回调Handler的dispatchMessage()分发消息方法,并将其传递到Handler的handleMessage()方法中。

使用Handler

1.handler.post()

new Thread(new Runnable(){
 		@override
		public void run(){
		 
		 //耗时操作

		 new Handler.post(new Runnable(){
		 	@override
		 	public void run{
		 		//更新UI
		 	}
		 });
	 }
}).start();

2.handler.sendMessage()

Handler handler=new Handler(){	
	@override
  public void handleMessage(Message msg){
    	 super.handleMessage(msg);
    	 String data=msg.obj.toString();//获取数据
    	   switch(msg.what){  //判断what标志
    	      case 0:
    	      /*
    	      更新UI
		*/
		break;
		case:
		……
    	 }
    }
}

new Thread(new Runnable(){
 @override
 public void run(){
 
 //耗时操作

~~Message message=new Message();//创建Message对象~~ 
Message message=Message.obtain();//从全局池返回一个Message对象,这样可避免上面一句那样对象的重复创建
message.what=0;//设置标志消息
message.obj="some data";//传递数据
handler.sendMessage(message);//发送消息
 }
}).start();

AsyncTask的简单使用

为了更加方便在子线程中对UI操作,安卓也提供了如AsyncTask封装好的工具类,其基本原理还是基于异步消息的处理机制,下面是AsyncTask的基本用法:

//AsyncTask是抽象类,须要创建一个类继承
class MyTask extends AsyncTask<1.Params,2.Progress,3.Result>{
 	@Override
        protected void onPreExecute() {
            super.onPreExecute();
            //此处执行异步处理前的初始化操作
            //比如显示进度条对话框
          }

        //在doInBackground方法中进行异步任务的处理.
        @Override
        protected Bitmap doInBackground(String... params) {//对应第一个泛型参数
            //获取传进来的参数
            String url = params[0];
		  …………
                     return bitmap;
                     //返回值传到onPostExecute方法
        }
    @Override
        protected void onProgressUpdate(Progress…) {//对应第2个泛型参数
        //利用后台传过来的参数值对UI元素进行更新
        //比如进度条的更新
        }
}

       
        @Override
        protected void onPostExecute(Bitmap result) {//对应第3个泛型参数
         //onPostExecute用于UI的更新.此方法的参数为doInBackground方法返回的值.
            super.onPostExecute(result);
                   //更新imageView
            imageView.setImageBitmap(result);
        }
}

总结来说,就是在 onPreExecute中执行初始化操作,在doInBackground中执行耗时任务,在onProgressUpdate中进行UI的更新操作,最后在onPostExecute中进行加载完成后的收尾工作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值