Android——processes,thread,AsyncTask(未完,待续。)

砾漠实例化
• 阅读 5573

由于没有学过操作系统。所以给这process,thread,AsyncTask三个搞糊涂了。

process老师没讲过,thread和AsyncTask只是讲了下使用。至于为什么要用AsyncTask也没多解释。

今天看了下Processes and Thread,安卓的官方API Guides.顺便练练英文。

看完后终于在头脑的概念清晰了一些。下面来做点笔记总结一下。

process

进程。一般来说,一个应用它的每一部分都是在同一个进程里面进行,但,我们可以去改变它。

通过改变manifest的android:process。

而当系统的内存不够用的时候,android系统会去杀掉一些进程,而杀死的对象也是有优先顺序的。例

如这样:

  1. Foreground process

    通常这个进程正在与用户在进行交互。只要满足下面这几点的其中一个点都算是foreground process

    这个Activity正在与用户在进行交互(Activity的onResume方法已经被调用)

    这个进程里面Service绑定了的activity正在与用户在进行交互

    这个Service正在运行在前台,startForeground()方法被调用

    这个service的这些回调函数的其中之一被调用(onCreate(), onStart(), or onDestroy())

    BroadcastReceiver 的onReceive() 被调用。

  2. Visible process

    这个进程没有一部分是在最前面的,但是它会影响到用户的屏幕显示的内容,它通常满足一下的其中一个点:

    它所在的activity不是在最前面,但对于用户来说还是可见的(它的onPause()方法被调用),就会出现这个情况,例如:一个在最前面的activity打开了一个dialog,这个时候,刚才的activity就会在dialog后面,自然就被挡住了。

    进程的service绑定了一个Visible Activity。

  3. Service process

    该进程所运行的service调用了startService() 方法,但又没满足以上两种情况的要求,即使该服务没有直接影响用户所看到的屏幕,但是它还是正在做用户关心的事情,例如,音乐播放器或者是正在下载数据。

  4. Background process

    该进程的activity没有直接给用户可见(通常onStop()方法被调用),该进程也没有直接影响用户所关心的事情,当系统资源不够用的时候,系统会随时把它杀掉,当然,通常会有好多这样的进程存在,这类进程也是有优先等级的,他们的排列方式是以用户使用该应用的最近时间排列。

  5. Empty process

    空进程。不解释

Thresds

当应用启动的时候,系统会自动创建一个线程给这个应用,这个线程叫主线程,也成为UI线程,因为这个主线程通常只是用来做UI的显示,和调用onCreat(),onStop()等方法。
做一些简单的事情。
如果需要做一些需要长一点时间或者复杂一些的事情,主线程会阻塞,主线程阻塞了5秒会引发"application not responding" (ANR) dialog的出现,严重影响用户体验。

这个时候我们就需要自行创建工人线程来解决这个问题。

但我们还得遵守两个原则:

  1. 不让主线程阻塞。

  2. 不在主线程(UI线程)外的线程进行UI的创建和修改。

Worker threads

例子:

public void onClick(View v) {
    new Thread(new Runnable() {
        public void run() {
            Bitmap b = loadImageFromNetwork("http://example.com/image.png");
            mImageView.setImageBitmap(b);
        }
    }).start();
}

这样做好像已经满足了我们所想的意思了,但其实不是这样,刚说了,我们不在主线程之外的线程作创建或者修改UI的动作。这里已经违反了。

安卓提供了几个在其他线程去求该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();
}

这个时候,访问网络不再主线程进行了,修改UI也脱离主线程,好像真的满足我们的需求了。其实。还是没有达到。

AsyncTask

如果我们都是这样做的话,线程会很多,很多的话就很难去管理,我们可能需要用Handler去管理我们的工人线程,在主线程传递信息过去Handler去处理。或者,还有一个更好的解决方法,就是使用AsyncTask类,它简单化地解决了我们刚才遇到的问题,可以使用到工人线程又可以和UI交互。

继承AsyncTask类后实现doInBackground() 回调方法,这个方法将会运行在后台线程(工人线程也称后台线程),要更新UI层,我们需要实现onPostExecute()方法,这个方法里面的结果是doInBackground() 传递过来的,这样我们就可以安全更新UI。我们只需在主线程调用 execute() 方法即可使用AsyncTask。

例子:

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);
    }
}

我们还可以在AsyncTask设置进度条,随时可以在doInBackground() 调用 publishProgress() ,然后用onProgressUpdate()更新进度条的UI显示。

这里经常会遇到一个问题就是,当我们使用工人线程的时候会出现 runtime configuration change 的错误,例如用户使屏幕横竖颠倒可能会destroy 我们的工人线程,这里还需要更深入地研究。可见Shelves的使用。

还有一点就是,AsyncTask不适合处理时间过长的任务,只适合处理较短时间的任务,例如几秒钟,如果要处理长时间的任务的话,android提供了几个更好的API给我们使用,如下:

java.util.concurrent包里面的Executor, ThreadPoolExecutor 和 FutureTask.

————————————————————————————————————————————————

有些内容是官网的API Guides或者reference里面直接翻译过来的,包挂一些代码也是。翻译得可能不是很好,请见谅。

未完。待续。。。。

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
4年前
Android 异步加载
一般会使用线程Thread、Timer或者使用AsyncTask,而这些操作都是在在后台另外开一个线程给我们找数据,具体得到的数据需要使用Handler去更新UI,AsyncTask也是一样使用到的Handler只是它将Handler封装在了onPostExecute执行操作中。使用过AsyncTask的同学都知道一个异步加载数据最少要
Wesley13 Wesley13
4年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
4年前
AsyncTask研究
AsyncTask研究侯亮(本文以Android7.0为准)1\.AsyncTask概述在Android平台上,要执行异步工作时,我们常常会用到AsyncTask。这个类可以算是历史悠久,早在Android1.5版时,它就存在了。AsyncTask的
Wesley13 Wesley13
4年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
4年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Python进阶者 Python进阶者
2年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这