Android 的进程和线程的基本知识

x-surfer:

1.android 的进程基本知识


        当应用程序第一次启动的时候,Android会启动一个Linux 进程和一个主线程,默认情况下,所有组件都会在该进程和线程中运行,Android会为每一个应用程序分配一个单独的Linux用户,Android在内存不足时,会杀掉一下进程保持优先级更高的线程运行。注意,这里的进程优先级是针对整个应用程序而言的,也就是说,相当于系统默认会给每个进程一个标志位,说明这个进程是属于什么进程,比如,当一个还程序被直接最小化到后台的时候,这个进程(也就是这整个应用程序)会被判定为后台进程。如果发送内存不足的情况,系统就会按照这个标志位的顺序来依次回收这些进程。




        Android 中的所有组件都在指定的进程中的主线程实例化的,对组件的调用也是由主线程发出的,每个实例不会建立新的线程,这就是为什么组件的操作不能太耗时、长时间阻塞主线程的操作,例如进行网络操作或者更新UI时,我们需要把它放到子线程中去执行




        前面说道Android在内存不足时,会回收一些内存,停止一些进程,对于不同的进程,有不同的优先级。进程从高到低有5个级别。





  • 前台进程:用户正在使用的进程,简单说,可以是在前台和用户交互的Activity进程(也就是最近一次onResume方法被调用时),比如下面的几种情况就属于前台进程。


  • 这个进程运行着一个正在和用户交互的Activity(这个Activity的onResume()方法被调用)。


  • 这个进程里有绑定到当前正在和用户交互的确Activity的一个service。


  • 这个进程里有一个service对象,这个service对象正在执行一个它的生命周期的回调函数(onCreate(), onStart(), onDestroy())


  • 这个进程里有一个正在的onReceive()方法的BroadCastReiver对象。


  • 可见进程:可见进程不包含前台组件,除非内存很低的时候前台进程又需要获取的资源,不然不会被终止。如下情况就是可见进程:


  • 这个进程中含有一个不位于前台的Activity,但是仍然对用户是可见的(这个Activity的onPause()方法被调用),这是很可能发生的,例如,如果前台Activity是一个对话框的话,就会允许在它后面看到前一个Activity。


  • 这个进程里有一个绑定到一个可见的Activity的Service。




  • 服务进程:运行着一个通过startService()方法启动的service,这个service属于除前两种情况外的service(也就是比如不跟当前activity绑定的service),在后台执行比较重要的任务,比如播放mp3,下载网络数据),如果你在编写程序的时候,想让这个后台执行的任务的优先级更高,就可以为他开启一个activity,或者任务通知栏显示,这样,这个本来是服务进程的进程就立马提升到了前台进程级别,不容易被系统回收。


  • 后台进程:运行着一个对用户不可见的activity(最近一次调用了额onstop方法 ),这些进程对用户体验没有直接英影响,在前面几种进程需要内存的时候,这个内存就会被回收,而且,这些不可见的进程保存在LRU(least recently used)列表,最近一个被用户看到的进程会被杀掉。    


  • 空进程:未运行任何程序组件,运行这些进程的唯一原因是作为一个缓存,缩短下次程序需要重新启动的时间,系统经常终止这些进程,这样可调节程序缓存和系统缓存的平衡。比如当用户点击应用的返回键时,如果系统退出表示当前系统处于空进程,并不是完全从系统内存中退出。





注意:


        系统在对进程进行重要度评级的时候,选取它的最高级别,比如,如果一个进程含有一个service和一个可视activity,进程将被归入一个可视进程而不是service进程。


        这一点非常重要,当一个进程被另一个更高的进程依赖时,这个进程的级别会增高,因为服务进程比一个后台activity的进程重要级要高,因此,一个要进程耗时工作的activity最好启动一个service来做这个工作,而不是开启一个子线程,特别是这个操作需要的时间比activity存在时间还要长的时候,比如:在后台播放音乐,向网上上传摄像头拍到的照片,使用service可以是进程最少获取到“服务进程”级别(甚至可以进一步升级),而不用考虑activity目前是什么状态。onReceive方法做费时工作的时候也应该启用一个服务而不是开启一个线程。




2.android 的结束进程的方法。


2.1   Android结束应用程序进程。会强制结束给出的包名下的所有进程,包括activity,service等等。 



  1. ActivityManager manager =(ActivityManager)getSystemService(ACTIVITY_SERVICE);


  2. manager.killBackgroundProcesses(getPackageName());



这个需要在配置文件中配置权限 



  1. <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>



2.2  android.os.Process.killProcess(pid),这个方法只能终止本程序的进程和又本程序创建的进程,还包括一些共享进程。



  1. Process.killProcess(Process.myPid());



2.3    System.exit(int code),这个方法会结束当前进程自身,当遇到一场无法正常执行时,可以通过这个方法强制退出。需要注意的是,这个方法和 Process.killProcess(pid);会导致进程非正常退出,也就是说,进程退出时不会去执行Activity的onPause、onStop和onDestroy方法,所以很有可能会错过保存数据的机会。


2.4    利用反射调用forceStopPackage来结束进程



  1. Method forceStopPackage = am.getClass().getDeclaredMethod("forceStopPackage",String.class);


  2. forceStopPackage.setAccessible(true);


  3. forceStopPackage.invoke(am, yourpkgname);



需要在配置文件添加定义



  1. android:sharedUserId="android.uid.system"   



需要添加权限



  1. <uses-permissionandroid:name="android.permission.FORCE_STOP_PACKAGES"></uses-permission>




评论
热度(5)