android的Task管理

来源:互联网 发布:windows同步时间出错 编辑:程序博客网 时间:2024/05/21 08:52

Task and the back stack  

   Android应用程序由多个activities组成,系统将这些activities按照tasks归类。每一个task把一系列activities表示为一个stack,当用户离开时,activities被放到stack中,当用户浏览回来时,activities被推送出来。这个被叫做back stack。当用户打开一个与当前的activity没有联系的一个新的activity时,新的task就会被创建。每一个task有自己的back stack。 

 

   所有ui事件都在主线程,或者叫ui线程中触发。你点击的每一个按钮通过主线程分发并触发一个事件。因此,使用work threads来处理长时间运行的操作就变得很重要。但是,更新UI就变得不是线程安全。如果你试图通过一个work threads更新UI,会导致异常。android 提供了很多解决这个问题的API:

   The Activity.runOnUiThread method
   The View.post, View.postDelayed, and View.postInvalidate methods
   The AsyncTask class
   Message handlers

   对于同一个activity在back stack中出现多次是有可能。当同一个activity可以从不同的地方被启动的时候,就会发生这种情况。你需要小心这种情形,因为你很容易消耗大量的资源,存储相同的activity。对用户来说,这也是很郁闷的事情,因为他们需要重复的按Back键来退出你的App。 

处理配置更改

     Android app经常碰到的一个情况是处理设备配置的改变。什么是设备配置改变呢,最基本的一个就是旋转手机时方向的改变。 这个会导致手机从横屏转为竖屏。这个改变导致你当前的activity销毁后重新创建。 此时,如何保存你app的输入数据和状态呢?

    你应该在onPause方法中保存数据。但是,这个应该只在用户觉得数据重要的时候才做。在这种情况下,你要保存的数据仅仅与当前存在的activity实例有关,为了实现这个,你可以通过onSaveInstanceState方法来实现。与onPause()方法不同,onSaveInstanceState并不总是被调用,它只有在activity要被销毁并且很可能被重建时才调用。你应该使用onSaveInstanceState来重新创建activity的状态。 这个的典型应用就是保存list中当前的位置,当方向发生变化时,你仍可以保持当前的位置。 

避免ANRS

   一个android应用在自己的进程运行,在一个单独的线程中运行。为了保证app的响应,android限制了函数的时间。如果某个函数超过时间限制,Application Not Responding对话框就会出现,询问要等待还是强制退出。    

StrictMode

          Android2.3引入了一个新的开发工具,叫做StrictMode。这个工具会检测在主线程中进行的磁盘或者网络操作,并对开发者发出警告。

            StrictMode并不能检测到主线程中出现的所有磁盘和网络操作。尤其,在jni中出现的就不会被检测到。

   在当前线程中声明StrictMode的方法:

          StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                 .detectAll() //检测磁盘和网络操作。
                 .penaltyLog() //打印警告日志。
                 .penaltyDialog()//显示警告对话框。

                 .build());

      检测所有线程的方法:

      StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                      .detectAll()
                      .penaltyLog()
                      .penaltyDeath()
                      .build());

后台Task                    

 handlers and message queues

   在后台运行线程是一个防止阻塞UI线程的好方法,但是,当task完成后,你通常需要更新UI。为了实现这个,你可以使用Handler class。Handlers在handleMessage方法中处理消息。

   通常,一个Handler实例与创建它的线程绑定(通常是主线程),给UI线程绑定一个handler提供了一个异步更新UI的灵活方法。但是,你也可以在一个单独的线程中运行handler,通过提供一个可选择的Looper实例。 A looper用来为一个线程管理消息循环。使用looper,你可以发送消息,任何一个线程实例都可以让他们执行。

    Looper类创建和管理一个叫MessageQueue对象,这个对象控制线程所有的消息。UI线程本身已经有了一个message Queue和looper供你使用。

             Activity.runOnUIThread也经常被用到。

AsyncTask

             通过继承AsyncTask类,你可以创建一个简单的线程来实现后台的task,并将结果发布到UI线程。

    下面是它的简单用法:

       private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
           protected Long doInBackground(URL... urls) {
            while (true) {
                      // Do some work
                        publishProgress((int) ((i / (float) count) * 100));
                        }
            return result;
           }

           protected void onProgressUpdate(Integer... progress) {
                  setProgressPercent(progress[0]);
           }
           protected void onPostExecute(Long result) {
                  showDialog(“Result is “ + result);
           }
         }
 

原创粉丝点击