安卓线程与进程
这个安卓的进程其实我感觉就是一个Activity就可以自己来一个进程,在我们的AndroidManifest.xml这个文件中我们可以通过:android:process="XXX"
来指定我们的进程,是否要新的一个进程,这个默认就是我们的包名。
进程优先级
因为安卓是手机的操作系统,内存少一些,所以他有个自动杀死进程的一个机制,主要是用来杀死一些不太重要的进程,在我们内存不太充足的条件下。
- 前台进程
- 可见进程
- 服务进程
- 后台进程
- 空进程
这个看名字基本就能明白,可见进程就是我们虽然不可见,其实也就是不能进行UI的操作了,比如说我们的一个程序,打的第二个Activity的时候他就变成了可见进程,空进程就是我们退出的进程,后台进程是我们虽然回到了主窗口,但是我们没有退出。
安卓会从下到上依次删除进程。
handle消息处理机制
这个东西就和Windows下面的消息循环很像,主要应对的是,子线程中我们不能对主线程的UI进行操作。
1 | try { |
run方法中写这个就代码,这个handler使我们自写的。
1 | private Handler handler = new Handler() |
很简单,我们重写这个handleMessage这个方法,这个对象是在我们的主线程的,所以可以操作UI,当我们调用sendMessage
这个方法的时候我们就会接受到这个消息,我们可以检查下是不是在主线程,确实是在主线程,输出为true。
当然我们还有一种就是延迟执行,意思就是隔几秒才进行UI的操作:
1 | handler.postDelayed(new Runnable() { |
这个就是所在10s之后执行,测试中发现同样可以操作UI。
但是要注意的是,我们并不能在子线程中直接创建这个Handler对象,因为我们主线程中拥有Looper
对象,而子线程中没有,所以我们先要给他准备一个,具体的操作代码:
1 | Looper.prepare();//Looper初始化 |
但是我们下面的代码就没办法执行了,因为那个loop就是在哪里一直死循环了,其实主线程的UI操作也就是这样死循环,但是为什么不会出现ANR的这个异常,这个是因为Linux的一些原因。
AsyncTask
这个就是很方便很好地一个东西,用来新建线程并且可以操作UI,我们需要继承这个类,然后重写一些方法,他是一个泛型,又是那个需要传入的参数,第一个是我们后台运行所要接受的参数类型,第二个是我们进行数据更新的时候,所要传入的参数类型,第三个是我们后台运行的返回值的参数(传递给onPostExecute
方法的)。
1 | class MyAsy extends AsyncTask<String, String, String> |
一般写在内部类中,好调用,当我们执行对象的execute
方法的时候,我们先执行onPreExecute
方法,也就是一些准备操作,在主线程中,比如我们的加载对话框出现,然后执行doInBackground
方法,是在子线程中执行,传进来的参数也就是我们execute
的时候传进来的可变长度的参数,返回值是提供给onPostExecute
方法(这个方法运行在主线程中)的,在我们加载的过程中可能会报告进度给UI,onProgressUpdate
这个方法就是用来接收进度的,在主线程中,用来操作进度条的。
execute
和doInBackground
的参数以及: 是第一个泛型onProgressUpdate
:这个的参数是第二个泛型onPostExecute
的参数和doInBackground
的返回值是第三个泛型
AsyncTask这个类内部有一个静态的线程池,是用来要用到线程的时候拿出线程用的。
在主线程中调用:
1 | MyAsy ma = new MyAsy(); |
这样我们就可以进行子线程中操作了。
遗留线程处理,安卓当中主线程结束,子线程还不结束,这个和Windows中有点区别,所以我们需要主线程结束之后子线程也要结束,我们可以设置一个标志位,在主线程销毁的时候,将这个标志位设置为false,子线程检查到是false的时候,就结束任务就可以了。