本文为Android的系统信息相关知识整理,具体参考了

  • 《Android开发艺术探索》第十章 Android的消息机制 + 第十一章 Android的线程和线程池
  • 《第一行代码》第九章 后台默默的劳动者,探究服务

因为Android的UI线程是不安全的,所有的UI操作(View相关)必须在主线程中进行。

1. 使用句柄进行异步消息处理(Handler法新建子线程)

Handler 法的实例如下:

 private Handler handler = new Handler() {    public void handleMessage(Message msg) {        switch (msg.what) {        case UPDATE_TEXT:            //  在这里可以进行UI操作            text.setText("Nice to meet you");            break;        default:            break;        }    }};@Overridepublic void onClick(View v) {    switch (v.getId()) {    case R.id.change_text:        new Thread(new Runnable() {            @Override            public void run() {              Message message = new Message();              message.what = UPDATE_TEXT;              handler.sendMessage(message); //  将Message 对象发送出去            }            }).start();        break;    default:        break;    }}

Android 中的异步消息处理的原理
Android的异步消息处理由四部分组成:

  • Message,线程之间传递消息。
  • Handler,处理者,处理和发送消息。发送使用sendMessage(),处理使用handleMessage()。
  • MessageQueue,消息队列,存放所有通过Handler发送的消息。每个线程只有一个MessageQueue对象。
  • Looper,是每个线程中MessageQueue的管家,调用Lopper的loop()方法后,就会进入到一个无限循环中,每当发现MessageQueue中存在一条消息,就会把它取出传给Handler处理。每个线程只有一个Looper对象

Android 中的异步消息处理的流程

  1. 在主线程中创建一个Handler对象,重写handleMessage()方法。
  2. new Thread(new Runnable() {...}).start()新建子线程,在需要进行UI操作时,新建一个Message对象,并通过sendMessage()方法发送出去。
  3. 这条消息被添加到MessageQueue队列中等待被处理。
  4. Looper一直尝试从MessageQueue中取出待处理消息,这条新消息被分发到Handler的HandleMessage()方法中。此处的handleMessage()是在主线程中运行的,可以再此方法中处理UI

2. 使用AsyncTask

Handler法比较复杂,所以为了方便,Android提供了AsyncTask来处理耗时操作,AsyncTask是基于异步消息处理机制的,仅仅是做了个封装。

首先是小栗子:

class DownloadTask extends AsyncTask {        //后台任务开始执行之前调用,用于进行一些界面上的初始化操作,比如显示一个进度条对话框等。    @Override    protected void onPreExecute() {        progressDialog.show(); // 显示进度对话框    }    //这个方法中的所有代码都会在子线程中运行,我们应该在这里去处理所有的耗时任务。    @Override    protected Boolean doInBackground(Void... params) {        try {            while (true) {                int downloadPercent = doDownload(); // 这是一个虚构的方法                publishProgress(downloadPercent);//downloadPercent就是onProgressUpdate()中的values[0]                if (downloadPercent >= 100) {                    break;                }            }        } catch (Exception e) {            return false;        }        return true;    }    //当在后台任务中调用了publishProgress(Progress...)方法后,这个方法就会很快被调用,方法中携带的参数就是在后台任务中传递过来的。在这个方法中可以对 UI 进行操作,利用参数中的数值就可以对界面元素进行相应地更新。    @Override    protected void onProgressUpdate(Integer... values) {        // 在这里更新下载进度        progressDialog.setMessage("Downloaded " + values[0] + "%");    }    //当后台任务执行完毕并通过 return 语句进行返回时,这个方法就很快会被调用    @Override    protected void onPostExecute(Boolean result) {        progressDialog.dismiss(); // 关闭进度对话框        // 在这里提示下载结果        if (result) {            Toast.makeText(context, "Download succeeded",            Toast.LENGTH_SHORT).show();        } else {            Toast.makeText(context, " Download failed",            Toast.LENGTH_SHORT).show();        }    }}

使用 AsyncTask 的诀窍:

  • 在 doInBackground()方法中去执行具体的耗时任务
  • 在 onProgressUpdate()方法中进行 UI 操作
  • 在 onPostExecute()方法中执行一些任务的收尾工作

启动子线程:在主线程中new DownloadTask().execute();
doInBackground()中,一定不要进行UI操作!!!!那是在子线程中!!!

更多相关文章

  1. Android 应用语言切换的三种方法
  2. Android CheckBox中设置padding无效问题解决方法
  3. Android 异步消息处理机制 让你深入理解 Looper、Handler、Messa
  4. Android设备Root检测方法
  5. Android Studio中创建Selector文件的方法
  6. blcr加速android启动速度遇到的问题及解决方法
  7. Android 公共库的建立方法
  8. 浅谈Android中的 Fragment、生命周期回调方法 以及使用

随机推荐

  1. Android(安卓)源码分析问题(三)—— 通过事
  2. 『Android自定义View实战』自定义带入场
  3. Android真机测试 连接本地服务器 手机测
  4. 2020年Android开发的未来发展方向该如何
  5. 简述android线程间消息处理机制(Looper、H
  6. Android(安卓)Studio 一些方便使用的设置
  7. Andriod内嵌HTML5项目构建以及整包更新配
  8. [置顶] android 多媒体和相机详解六
  9. Android(安卓)XML shape 标签使用详解(ap
  10. Android车轮之图片加载框架Android-Unive