一、进程的基本状态
进程经常讨论的基本状态为:就绪状态(Ready)、运行状态(Running)、阻塞状态(Blocked)。此外,还包括不常讨论的创建和结束。
就绪状态:当进程已分配到除CPU以外的所有必要资源后,只要再获得CPU,便可立即执行,进程这时的状态称为就绪状态。在一个系统中处于就绪状态的进程可能有多个,通常将它们排成一个队列,称为就绪队列。
运行状态:进程已获得CPU,其程序正在执行。在单处理机系统中,只有一个进程处于执行状态; 在多处理机系统中,则有多个进程处于执行状态。
阻塞状态:正在执行的进程由于发生某事件而暂时无法继续执行时,便放弃处理机而处于暂停状态,亦即进程的执行受到阻塞,把这种暂停状态称为阻塞状态,有时也称为等待状态或封锁状态。致使进程阻塞的典型事件有:请求I/O,申请缓冲空间等。通常将这种处于阻塞状态的进程也排成一个队列。有的系统则根据阻塞原因的不同而把处于阻塞状态的进程排成多个队列。
三种状态的切换如下图所示:
二、线程的基本状态
线程的基本状态包括:派生,阻塞,激活,调度,结束。可以通过线程对象的isAlive()方法,来判断线程对象的状态(新建或者死亡都会返回false)
派生(New):线程在进程内派生出来,它即可由进程派生,也可由线程派生。
阻塞(Block):如果一个线程在执行过程中需要等待某个事件发生,则被阻塞。
激活(Unblock):如果阻塞线程的事件发生,则该线程被激活并进入就绪队列。
调度(Schedule):选择一个就绪线程进入执行状态。
结束(Finish):如果一个线程执行结束,它的寄存器上下文以及堆栈内容等将被释放。
五种状态的切换如下图所示:
wait(): 当前线程等待若干ms,当前线程自动释放同步监视器,线程进入等待状态(阻塞),直到其他线程调用了该同步监视器的notify()或者notifyAll方法。
notify():唤醒在同步监视器上等待的单个线程,若有多个线程等待,则任意选择其中一个。
notifyAll():唤醒在此同步监视器上等待的所有线程。sleep():程序暂停执行指定的时间,让出cpu给其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。线程不会释放对象锁。
进程等级
1.前台进程Foreground process
一个进程是前台进程,对于activity而言,此时的activity正在与用户处于交互的情况;要是一个服务,要不就是执行了运行在前台的方法
startForeground()或者是和activity的互动是绑定的;或者是调用的自己的生命周期;要是广播接受者此调用了onReceive()方法.
2.可见进程(Visible process)
一个过程,没有任何在前台的组件,但是仍然会影响用户所看到的屏幕上.认为是可见的. 调用了activity的onPause()方法,服务所绑定的activity是一个可见的activity
3.服务进程(Serviceground process)
通过startService来开启的一个服务,比如是服务开启的音乐的播放和下载数据
4.后台进程(Background process)
5.空进程 最容易被杀死回收(Empty process)
没有任何东西在内运行的进程。
Application
application是用来保存全局变量的,并且是在package创建的时候就跟着存在了。所以当我们需要创建全局变量的时候,不需 要再像j2se那样需要创建public权限的static变量,而直接在application中去实现。只需要调用Context的getApplicationContext或者Activity的getApplication方法来获得一个application对象,再做出相应 的处理。
自定义Application用途
- 为得到一个Application对象提供便捷
- 封装一些通用操作
- 初始化一些全局的变量数据
新建一个MyApplication并让它继承自Application
public class MyApplication extends Application{ private static Context mContext; @Override public void onCreate() { super.onCreate(); mContext = getApplicationContext(); } public static Context getInstance() { return mContext; } }
在AndroidManifest文件中指定自定义的Application
<application android:name=".MyApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme" />
不能够在自定义的Application类的构造方法里初始化一些需要Context引用操作得到的数据,例如getResources()、getPackageName()、getSystemService()等等。一旦这样做,应用程序已启动就会报控指针的错误。我们应该在onCreate()方法中初始化。
ContextWrapper中有一个attachBaseContext()方法,这个方法会将传入的一个Context参数赋值给mBase对象,之后mBase对象就有值了。而我们又知道,所有Context的方法都是调用这个mBase对象的同名方法,那么也就是说如果在mBase对象还没赋值的情况下就去调用Context中的任何一个方法时,就会出现空指针异常
Application方法执行顺序:
自定义Application采用单例模式
Application全局只有一个,它本身就已经是单例了,无需再用单例模式去为它做多重实例保护了。
public class MyApplication extends Application { private static MyApplication app; public static MyApplication getInstance() { return app; } @Override public void onCreate() { super.onCreate(); app = this; } }
生命周期:
onCreate 在创建应用程序时创建
实现APP崩溃后自动重启或者捕获异常信息:
onTerminate 当终止应用程序对象时调用,不保证一定被调用,当程序是被内核终止以便为其他应用程序释放资源,那么将不会提醒,并且不调用应用程序的对象的onTerminate方法而直接终止进 程
onLowMemory 当后台程序已经终止资源还匮乏时会调用这个方法。好的应用程序一般会在这个方法里面释放一些不必要的资源来应付当后台程序已经终止,前台应用程序内存还不够时的情况。
onConfigurationChanged 配置改变时触发这个方法
自定义application中创建一个UncaughtException对象:
- private Thread.UncaughtExceptionHandler restartHandler = new Thread.UncaughtExceptionHandler() {
- public void uncaughtException(Thread thread, Throwable ex) {
- restartApp();
- }
- };
定义重启方法:
- public void restartApp() {
- Intent intent = new Intent(getApplicationContext(), FlashActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivity(intent);
- RxBus.getDefault().post(RxBusConstant.FINISH);//把你退出APP的代码放在这,我这里使用了rxbus关闭所有Activity
- android.os.Process.killProcess(android.os.Process.myPid());
- }
最后在application的oncreat中注册这个handler就大功告成了:
- Thread.setDefaultUncaughtExceptionHandler(restartHandler);