`
he91_com
  • 浏览: 411132 次
文章分类
社区版块
存档分类
最新评论

Android基础之进程和线程 AsyncTask , Handler

 
阅读更多

进程Process

默认情况下,一个应用程序的所有组件都在一个进程之中.

但也可以通过Manifest.xml文件中的android:process来指定某个<activity><service><provider><receiver>控件属于哪个进程,也可以为<application>指定进程

通过android:process可以让同一个应用的组件运行在不同的进程中,也可以使不同应用的组件运行在一个进程中

在系统内存较低的时候,Android系统会按一定规律选择性关闭一些进程.


线程Thread

不要阻塞UI线程(main线程)

不要从UI线程之外的线程来操纵UI,比如imgView.setImageBitmap(...)等


从别的线程来更改UI时,可以用Activity.runOnUiThread(Runnable),View.post(Runnable),View.postDelayed(Runnable,long)

public void onClick(View v) {
  new Thread(new Runnable() {
    public void run() {
      final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
      mImageView.post(new Runnable() {
        public void run() {
          mImageView.setImageBitmap(bitmap);
        }
      });
    }
  }).start();
}
但遇到更加复杂的情形时会很乱,应该使用一个Handler或者继承AsyncTask类,


AsyncTask异步任务类

继承AsyncTask类时,不用自己去管理线程,onPreExcute是在调用前执行的块,onProgressUpdate,onPostExcute都是在原来的线程中进行的操作

doInBackground是在新的线程中的操作,其返回值返回给了onPostExcute方法

任何时候都可以在doInBackground中使用publishProcess()方法来执行onProgressUpdate.

任何时候都可以取消新线程.


public void onClick(View v) {
  new DownloadImageTask().execute("http://example.com/image.png");
}

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
  /** The system calls this to perform work in a worker thread and
   * delivers it the parameters given to AsyncTask.execute() */
  protected Bitmap doInBackground(String... urls) {
    return loadImageFromNetwork(urls[0]);
  }
  
  /** The system calls this to perform work in the UI thread and delivers
   * the result from doInBackground() */
  protected void onPostExecute(Bitmap result) {
    mImageView.setImageBitmap(result);
  }
}

Handler

Handler的作用
1.可以安排在未来的某时进行一些操作
2.在不同的线程中执行一些操作,并支持线程之间的通信

一个Handler对应着一个线程以及它的消息队列
当你创建一个Handler的时候,它就和创建它的线程/消息队列相绑定
之后,这个handler就要开始处理这个消息队列中的消息了
Looper是一个消息队列的监听器,并不是每一个thread都有looper,主线程在创建时,系统自动为其创建了looper,而用HandlerThread创建的Thread都有looper

可以构建Handler对象与Looper沟通,以便send新消息到messageQueue.
或者接收Looper从MessageQueue中取出的消息.



在子线程中使用主线程的Handler发送消息(向主线程的MessageQueue发送消息)
拿一个常用的功能举例子:比如要从网络上获得一张图片,并且更新到当前Activity的imageView上
首先要新建一个线程,在其run方法中来从网络上下载图片 //下载这种操作比较费时,当然要用异步
在Activity中调用这个线程.start()来启动线程
在线程中下载完成时引用主线程的handler.sendMessage()来通知主线程下载好了开始更新 //在这个功能中handler是主线程的,消息队列也是主线程的,此时的主线程没有必 有handler和looper,也就没必要用HandlerThread,普通的Thread即可
在主线程的handler中的handleMessage方法中更新UI //handler是主线程的,当然里面的handleMessage方法也在主线程中执行,在UI线程中更新UI
具体实现如下:
在Activity中:
Handler activityHandler=new Handler(){ //因为handler需要重写handlMessage方法来决定其处理消息的方式,要new一个
public void handleMessage(Message msg){
if(msg.arg1==UPDATE_UI){
imageView.setBitmap(....); //如果接受的消息一个参数是UPDATE_UI常量,更新UI
}
}
}

启动一个新的线程:
class ImageThread extends Thread{
public void run(){
//从网络上获得图片
//获得完毕之后
Message msg=new Message(); //生成一个消息对象
msg.arg1=UPDATE_UI; //设置其参数
activityHandler.sendMessage(msg); //调用主线程的activityHandler,向主线程的消息队列发送消息
//或者这里调用
}
}

ImageThread it=new ImageThread();
it.start();


所以如果两个线程之间要相互通信,就要两个线程都拥有handler,looper,消息队列了



而还有handler.post(Runnable) postDelayed(Runnable,long)等,这些线程执行都是在调用它们的handler所在线程执行的








一些简单的实验:
//创建一个Hanlder对象
Handler handler=new Handler();
//把所要进行操作的线程对象用handler.post()或者.postDealyed()方法添加到线程队列中
handler.post(updateThread); //handler.removeCallbacks(updateThread)来从消息队列中去除掉这个线程
Runnable updateThread =new Runnable(){
public void run(){
//线程中的复杂操作
System.out.println("Thread Start");
}
}



//下面这个是可以处理消息的Handler

Handler handler=new Handler(){

public void handleMessage(Message msg){

System.out.println(msg.arg1+"");

}

}


handler.post(updateThread); //把新线程加入到消息队列中

Runnable updateThread=new Runnable(){

public void run(){

Message msg=handler.obtainMessage(); //获得handler中消息队列的一个消息

msg.arg1=50; //为msg携带的值赋值

handler.sendMessage(msg); //把消息加入handler的消息队列

}

}

但是上述两个Handler其实都没有真正的启动另外的线程,而还是在原来的main线程中执行!!!!


如果要使用Handler来生成新线程来执行复杂操作可以使用HandlerThread类,

HandlerThread类会启动一个带有looper的新的线程,而这个looper一会儿可以用来创建Handler

HandlerThread handlerThread=new HandlerThread("handler_thread"); //创建一个HandlerThread线程对象,如果要执行有意义的操作,继承这个类,重写run方法

handlerThread.start();

MyHandler myHandler=new MyHandler(handlerThread.getLooper()); //用新线程的looper来创建一个handler对象


Message msg=myHandler.obtainMessage();

msg.sendToTarget();



class MyHandler extends Handler{

public void handleMessage(Message msg){

}

}


分享到:
评论

相关推荐

    android 异步任务 Binder 线程间交互 Handler 迭代器模式

    以上内容涵盖了Android中线程交互的基础知识,包括AsyncTask的使用、Binder机制的理解、Handler和MessageQueue在多线程通信中的角色,以及迭代器模式在数据处理中的应用。理解并熟练掌握这些知识点,对于成为一名...

    详解Android进程和线程

    Android进程和线程是Android应用程序运行的基础,理解这两个概念对于开发高质量的Android应用至关重要。在Android系统中,每个应用都是一个独立的Linux进程,这意味着它们在各自的沙箱环境中运行,互不影响,提高了...

    Android 进程和线程

    在Android系统中,进程和线程是应用程序运行的基础,它们决定了程序如何管理和执行任务。深入理解这两个概念对于优化应用性能、提高用户体验至关重要。 首先,我们要明白什么是进程。在计算机科学中,进程是程序的...

    Android-可保持线程日志统一输出多线程不混乱

    6. **异步日志处理**:使用Handler或者AsyncTask等机制,将日志的打印工作放到主线程或者一个专门的日志处理线程,避免因日志输出导致的阻塞。 7. **日志框架**:使用如Logback、Log4j等更强大的日志框架,它们提供...

    Android-详细解读AsyncTask的黑暗面以及一种替代方案

    在Android开发中,AsyncTask是一种常用的轻量级异步任务处理框架,它使得开发者可以在UI线程之外执行耗时操作,以避免应用因为阻塞主线程而引发的ANR(Application Not Responding)错误。然而,尽管AsyncTask简单...

    Android下线程与进程

    总之,理解和掌握Android中的线程与进程是开发高质量应用的基础,它们直接影响到应用的响应速度、稳定性以及资源利用率。`WorkThreadDemo`这样的实例代码可以帮助开发者更好地理解并实践这些概念。

    Android 应用程序模块 应用, 任务, 进程, 和线程--千锋培训

    在Android应用开发中,理解应用程序模块、任务(Tasks)、进程(Processes)和线程(Threads)的概念至关重要。这些组件是构建高效、响应且资源管理良好的应用程序的基础。 1. **应用程序模块(Application Modules...

    android 进程与线程 - 开发文档翻译 - 进程.doc

    在Android系统中,进程和线程是应用程序执行的基础。每个应用组件的启动都可能伴随着新进程的创建或已有进程的重用。默认情况下,同一应用的所有组件在同一进程中运行,共享一个主线程。这是因为主线程负责处理用户...

    android进程和新城之间的通信

    在Android系统中,进程和线程的通信是应用程序运行的核心组成部分。Android系统为每个应用程序启动一个单独的Linux进程,这个进程在默认情况下承载了应用程序的所有组件,如Activity、Service等。每个应用程序至少有...

    线程,线程池与Handler的用法

    在Android开发中,线程和线程池是处理异步任务的重要工具,而Handler则是用于在主线程和子线程之间通信的关键组件。本篇文章将深入探讨这些概念,以及它们在实际应用中的用法。 首先,让我们理解什么是线程。线程是...

    Android 线程和线程池核心技术-走进线程世界 (一)

    合理利用AsyncTask、Runnable、Thread、Handler、Looper、线程池和线程同步机制,能帮助开发者设计出更加健壮和高效的Android应用。在实际开发中,应根据任务特性和需求,选择最适合的线程管理方式。通过Demo实践,...

    Android多线程处理[参考].pdf

    Android多线程处理是移动应用开发中的关键概念,...开发者需要熟练掌握Handler、Message、Looper、AsyncTask等工具,以及线程同步和进程管理的相关知识,合理安排任务执行,避免主线程阻塞,确保应用的高效和稳定运行。

    Android开发中的多线程编程技术

    - **Looper、Handler和Message**:这是Android中处理UI线程与后台线程交互的主要方式。 - **AsyncTask**:提供了一种简便的方式来执行后台计算任务,并将结果更新到UI线程。 - **IntentService**:专门用于处理耗时...

    Android实现多线程下载

    可以使用Handler或BroadcastReceiver来实现进程间的通信,将进度信息传递到UI线程。 8. **错误处理和重试机制**: 在下载过程中可能会遇到各种错误,如网络中断、服务器响应错误等。为了保证下载的可靠性,需要...

    Android中的高效多线程

    - **消息机制**:`Handler`和`Looper`机制是Android中最常用的线程间通信方式之一。 3. **线程管理与控制**: - **线程池**:使用`ExecutorService`管理一组工作线程,避免频繁创建和销毁线程带来的开销。 - **...

    android多线程

    在深入探讨Android多线程之前,我们首先理解进程和线程的基本概念。**进程**是正在运行的程序实例,每个进程拥有自己独立的内存空间和系统资源。而**线程**则是进程内的执行单位,允许多个线程在单个程序中并发执行...

    Android游戏开发之多线程的操作方式源码

    本资源"Android游戏开发之多线程的操作方式源码"正是针对这一主题提供了深入的学习材料,适合对Android游戏开发感兴趣的开发者进行研究和实践。 首先,我们要理解Android系统的线程模型。在Android中,所有的应用...

    android多线程模型和service分析

    但是,直接使用Java的线程API在Android开发中并不常见,因为Android提供了更高级的API如`AsyncTask`、`IntentService`以及`Executor`框架,它们封装了线程的创建与管理,简化了多线程编程的复杂度。 #### Service在...

    Android多线程处理[归类].pdf

    Android进程的理解是多线程处理的基础。每个Android程序都有一个与之关联的Linux进程和主线程。进程按其重要性分为五个级别:前台进程、可见进程、服务进程、后台进程和空进程。这些级别的划分决定了Android系统在...

    Android多线程处理 详解

    #### 一、Android进程与线程基础 在深入探讨Android中的多线程处理之前,我们需要先理解Android的基本进程和线程模型。 **Android进程:** 当一个Android应用首次启动时,系统会为该应用创建一个Linux进程。此进程...

Global site tag (gtag.js) - Google Analytics