版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Google Android多线程及消息处理多线程及消息处理on android本章内容本章内容nAndroid多线程概述多线程概述创建线程创建线程操作线程操作线程nUI线程与非线程与非UI线程线程n多线程中的常用类多线程中的常用类Handler类类AsyncTask类类Timer定时器定时器nAndroid多线程通信机制多线程通信机制n使用线程使用线程任何耗时的处理过程都会降低用户界面的响应速度,甚至导任何耗时的处理过程都会降低用户界面的响应速度,甚至导致用户界面失去响应,当用户界面失去响应超过致用户界面失去响应,当用户界面失去响应超过5秒钟,秒钟,Android系统会允许用户强行关闭应用程
2、序系统会允许用户强行关闭应用程序较好的解决方法是将耗时的处理过程转移到子线程上,这样较好的解决方法是将耗时的处理过程转移到子线程上,这样可以避免负责界面更新的主线程无法处理界面事件,从而避可以避免负责界面更新的主线程无法处理界面事件,从而避免用户界面长时间失去响应免用户界面长时间失去响应多线程概述多线程概述n概述概述 表示一个程序的表示一个程序的多段语句同时执行多段语句同时执行,但并不等于多次启动一,但并不等于多次启动一个程序,操作系统也不会把每个线程当作独立的进程来对待。个程序,操作系统也不会把每个线程当作独立的进程来对待。n线程和进程区别线程和进程区别两者的两者的粒度不同粒度不同,是两个不
3、同层次上的概念。进程是由,是两个不同层次上的概念。进程是由操作系统来管理的,而线程则是在一个程序(进程)内。操作系统来管理的,而线程则是在一个程序(进程)内。不同进程的代码、内部数据和状态都是完全独立的,而不同进程的代码、内部数据和状态都是完全独立的,而一个程序内的一个程序内的多线程是共享同一块内存空间多线程是共享同一块内存空间和同一组系和同一组系统资源,有可能互相影响。统资源,有可能互相影响。线程本身的数据通常只有线程本身的数据通常只有寄存器数据寄存器数据,以及一个程序执,以及一个程序执行时使用的堆栈,所以线程的切换比进程切换的负担要行时使用的堆栈,所以线程的切换比进程切换的负担要小。小。多
4、线程概述多线程概述n线程的状态和生命周期线程的状态和生命周期 一个线程从创建、启动到终止期间的任何时刻,总是处于一个线程从创建、启动到终止期间的任何时刻,总是处于下面五个状态中的某个状态。下面五个状态中的某个状态。创建状态创建状态 用用new运算符创建一个运算符创建一个Thread类或子类的实例对象,但此类或子类的实例对象,但此时还未对这个线程分配任何资源。时还未对这个线程分配任何资源。 就绪状态就绪状态 分配系统资源,由分配系统资源,由start()启动方法来完成。启动方法来完成。运行状态运行状态当可运行状态的线程被调度并获得当可运行状态的线程被调度并获得CPU等资源。等资源。多线程概述多线
5、程概述n线程的状态和生命周期(续)线程的状态和生命周期(续)阻塞状态阻塞状态 由于人为或系统的原因,线程必须停止运行,以后还可以恢由于人为或系统的原因,线程必须停止运行,以后还可以恢复运行的状态称为阻塞状态。复运行的状态称为阻塞状态。 终止状态终止状态 run()方法完成后或调用方法完成后或调用stop()或或destroy()方法方法 ,不,不能继续运行。能继续运行。多线程概述多线程概述n线程的生命周期及控制线程的生命周期及控制多线程概述多线程概述n线程控制基本方法线程控制基本方法方方 法法功功 能能currentThread() 返回正在运行的Thread对象yield()让出CPU,当前
6、线程进入就绪队列等待调度sleep()设置当前线程进入睡眠状态,时间为指定的毫秒数setName()设置当前线程名称getName()获取当前线程名称isAlive()判断线程是否还“活”着,即线程是否还未终止getPriority()获得线程的优先级数值setPriority()设置线程的优先级数值wait()当前线程进入对象的wait poolnotify()notifyAll()唤醒对象的wait pool中的一个/所有等待线程多线程概述多线程概述class SingleThread public void output() Thread t=Thread.currentThread()
7、; t.setName(单线程); t.setPriority(8); System.out.println(The running thread: + t); try for(int i=0; i 3; i+) System.out.println(Sleep time + i); Thread.sleep(500);/ 睡眠500毫秒 catch(InterruptedException e) System.out.println(thread has wrong); public class Test public static void main(String args) Single
8、Thread st=new SingleThread(); st.output(); The running thread: The running thread: ThreadThread单线程单线程,8,main,8,mainSleep time 0Sleep time 0Sleep time 1Sleep time 1Sleep time 2Sleep time 2单线程例单线程例多线程概述多线程概述n创建线程创建线程通过继承通过继承Thread类来创建线程类来创建线程class MyThread extends Thread public void run() / 线程需要完成的工作
9、public static void main() / 创建线程 Thread thread1 = new MyThread(); 多线程概述多线程概述n创建线程创建线程通过实现通过实现Runnable接口来创建线程接口来创建线程class MyThread implements Runnable public void run() / 线程需要完成的工作 public static void main() / 创建线程 Thread thread2 = new Thread(new MyThread(); UI线程与非线程与非UI线程线程 nUI线程线程当应用启动,系统会创建一个主线程(当应
10、用启动,系统会创建一个主线程(UI线程)线程)处理与处理与UI相关的事件相关的事件 如按键事件、用户接触屏幕的事件、屏幕绘图事件等如按键事件、用户接触屏幕的事件、屏幕绘图事件等系统不会为每个组件单独创建线程,在同一个进程里的系统不会为每个组件单独创建线程,在同一个进程里的UI组件都会在组件都会在UI线程里实例化,系统对每一个组件的线程里实例化,系统对每一个组件的调用都从调用都从UI线程分发出去线程分发出去从从UI线程中操作线程中操作UI组件是安全的组件是安全的非非UI线程中进行线程中进行UI操作不是线程安全的操作不是线程安全的UI线程与非线程与非UI线程线程 n非非UI线程线程非主线程非主线程
11、向向UI线程发出请求消息,由线程发出请求消息,由UI线程处理这些消息,并线程处理这些消息,并进行相关的进行相关的UI操作操作UI线程与非线程与非UI线程线程n非非UI线程线程UI操作错误操作错误public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); text = (TextView) findViewById(R.id.text); Thread t = new Thread() public void run() /非U
12、I线程 try Thread.sleep(3000); /睡眠3秒 catch (InterruptedException e) e.printStackTrace(); text.setText(UI Thread Test.); ; t.start(); /启动线程android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. UI线程与非线程与非UI线程线程n非非UI线程线程UI操作错误操作错误
13、public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); TextView text = (TextView) findViewById(R.id.text); text.setText(Sleep start.); try Thread.sleep(3000); /睡眠3秒 catch (InterruptedException e) e.printStackTrace(); text.setText(Sleep end.
14、);程序运行后,界面上开始是空白的,既没有之前的“Hello World, HelloDemoActivity!”字样,也没有“Sleep start.”字样,等待3秒钟后,界面上显示“Sleep end.” 多线程中的常用类多线程中的常用类nHandler类类 处理较为复杂的线程间通信及消息处理处理较为复杂的线程间通信及消息处理nAsyncTask类类 轻量级基于多线程的进行后台异步工作处理的类轻量级基于多线程的进行后台异步工作处理的类nTimer定时器定时器 定时器也是常用的实现多线程程序的方式定时器也是常用的实现多线程程序的方式多线程中的常用类多线程中的常用类nHandler类类非非UI
15、线程向线程向UI线程发出请求消息,由线程发出请求消息,由UI线程处理这些线程处理这些消息,并进行相关的消息,并进行相关的UI操作。这个发送消息和处理消息操作。这个发送消息和处理消息的过程由的过程由Handler类来协助进行处理类来协助进行处理在在UI线程中创建线程中创建Handler类的子类,并通过重写类的子类,并通过重写handleMessage(Message msg)方法来实现方法来实现UI操作操作当有其他线程向这个自定义子类的对象发送消息时,当有其他线程向这个自定义子类的对象发送消息时,handleMessage()方法会被调用,通过识别参数方法会被调用,通过识别参数msg的值的值 b
16、oolean sendMessage(Message msg)boolean sendEmptyMessage(int what)多线程中的常用类多线程中的常用类nHandler类类Message类用来封装所发送消息的值,可以通过类用来封装所发送消息的值,可以通过Bundle类来封装这些不同类型的值类来封装这些不同类型的值 void setData(Bundle data) Bundle getData() 两个两个int类型的域变量类型的域变量 一个一个Object类型的域变量作为额外的存储空间类型的域变量作为额外的存储空间Bundle类用于提供从字符串到某个具体值的映射,一类用于提供从字符
17、串到某个具体值的映射,一个个Bundle对象可以封装多个键值对对象可以封装多个键值对 void putXXX(String key, XX value) XXX getXXX(String key)多线程中的常用类多线程中的常用类public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); final TextView text = (TextView) findViewById(R.id.text); final Handle
18、r handler = new Handler() public void handleMessage(Message msg) /接收消息 super.handleMessage(msg); text.setText(Message Code: + msg.what); ;nHandler类类实现过程实现过程多线程中的常用类多线程中的常用类 Thread t = new Thread() public void run() try Thread.sleep(3000); catch (InterruptedException e) e.printStackTrace(); handler.s
19、endEmptyMessage(1); /发送消息 ; t.start(); /启动线程多线程中的常用类多线程中的常用类nHandler类类实例:使用多线程模拟秒表应用实例:使用多线程模拟秒表应用 多线程中的常用类多线程中的常用类nAsyncTask类类轻量级的基于多线程的进行后台异步工作处理的类轻量级的基于多线程的进行后台异步工作处理的类实现后台向实现后台向UI线程传递简单数据线程传递简单数据使用使用AsyncTask类的方法是创建一个子类,重写其相类的方法是创建一个子类,重写其相关的方法,然后在关的方法,然后在UI线程中使用线程中使用execute()方法运行方法运行这个自定义类即可这个自
20、定义类即可多线程中的常用类多线程中的常用类nAsyncTask类重写方法类重写方法onPreExecute():当后台任务使用:当后台任务使用execute()方法运行后,会方法运行后,会立即由立即由UI线程调用,一般用于初始化操作和在界面上显示后台任线程调用,一般用于初始化操作和在界面上显示后台任务的初始状态。务的初始状态。doInBackground(Params.):当:当onPreExecute()方法调方法调用结束后,由后台线程调用该方法,开始执行后台任务。在后台任用结束后,由后台线程调用该方法,开始执行后台任务。在后台任务执行过程中,可以调用务执行过程中,可以调用publishPr
21、ogress(Progress.)方方法向法向UI线程发布当前后台任务执行的状态,以便程序界面进行相线程发布当前后台任务执行的状态,以便程序界面进行相应的更新。应的更新。onProgressUpdate(Progress.):当后台线程调用:当后台线程调用publishProgress(Progress.)方法后,由方法后,由UI线程调用该方线程调用该方法进行法进行UI操作。操作。onPostExecute(Result):当后台任务全部执行完毕后,由:当后台任务全部执行完毕后,由UI线程调用该方法,更新界面的显示,或进行其他的后续操作。线程调用该方法,更新界面的显示,或进行其他的后续操作。p
22、ublic class HelloDemoActivity extends Activity public void onCreate(Bundle savedInstanceState) . text = (TextView) findViewById(R.id.text); new MyAsyncTask().execute(null); class MyAsyncTask extends AsyncTask public String doInBackground(String. params) try Thread.sleep(3000); publishProgress(50); c
23、atch (InterruptedException e) e.printStackTrace(); return ; public void onProgressUpdate(Integer. values) text.setText(value: + values0); 多线程中的常用类多线程中的常用类nAsyncTask类类实例:使用实例:使用AsyncTask类模拟进度变化类模拟进度变化 多线程中的常用类多线程中的常用类nTimer定时器定时器使用使用Timer类和类和TimerTask类可实现定时器的功能。但是类可实现定时器的功能。但是在定时器中也不能直接进行在定时器中也不能直接进行
24、UI操作,需要使用以下几种方操作,需要使用以下几种方式之一来间接地进行式之一来间接地进行UI操作操作通过通过Handler类处理类处理通过通过Activity.runOnUiThread(Runnable)方法方法通过通过View.post(Runnable)方法方法多线程中的常用类多线程中的常用类nActivity.runOnUiThread(Runnable action)该方法被调用后,如果当前线程是该方法被调用后,如果当前线程是UI线程,则立即启动线程,则立即启动由参数由参数action所指定的线程所指定的线程如果该方法被调用时的当前线程不是如果该方法被调用时的当前线程不是UI线程,则
25、由参数线程,则由参数action所指定的线程会被放入所指定的线程会被放入UI线程的事件队列中等线程的事件队列中等待处理待处理通常程序调用通常程序调用runOnUiThread()方法是在非方法是在非UI线程中线程中进行进行public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); text = (TextView) findViewById(R.id.text); TimerTask task = new TimerTask(
26、) public void run() Thread t = new Thread() public void run() text.setText(runOnUiThread(); ; runOnUiThread(t); /将t线程放入UI线程的事件队列中等待处理 ; Timer timer = new Timer(); timer.schedule(task, 3000);多线程中的常用类多线程中的常用类多线程中的常用类多线程中的常用类nView.post(Runnable action)action为待启动线程为待启动线程nrunOnUiThread()方法会将该线程放入方法会将该线程放
27、入UI线程线程的事件队列中等待处理的事件队列中等待处理post()方法是将该线程放入某个方法是将该线程放入某个View对象的消息队列对象的消息队列中等待处理。如果能将线程成功放入中等待处理。如果能将线程成功放入View对象的消息对象的消息队列中,队列中,post()方法返回方法返回true,否则返回,否则返回false public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); text = (TextView) findVi
28、ewById(R.id.text); TimerTask task = new TimerTask() public void run() Thread t = new Thread() public void run() text.setText(view.post(); ; text.post(t); /将t线程放入当前文本框对象的消息队列中等待处理 ; Timer timer = new Timer(); timer.schedule(task, 3000);多线程中的常用类多线程中的常用类多线程中的常用类多线程中的常用类nTimer定时器定时器实例:使用实例:使用Timer定时器实现手机内存监视器定时器实现手机内存监视器多线程中的常用类多线程中的常用类nTimer定时器定时器实例:使用实例:使用Timer定时器实现手机内存监视器定时器实现手机内存监视器Android多线程通信机制多线程通信机制nMessageQueue类类消息队列中可包含多个消息,按照先进先出原则依次处消息队列中可包含多个消息,按照先进先出原则依次处理。理。MessageQueue不需要由用户来进行创建和管理,不需要由用户来进行创建和管理,而是通过而是通过Looper类用来管理
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论