当前位置:首页 » 安卓系统 » android进程服务

android进程服务

发布时间: 2023-09-23 14:43:24

A. 请问android系统中的进程,任务,服务三者的区别和联系

进程是总称,包括第三方应用和系统应用以及系统底层模块。任务是你安装的第三方应用进程。而服务是系统模块进程。

B. Android提升服务进程优先级

在android应用开发时,我们经常会在后台开一个service,来处理一些业务操作。最近公司的一个项目就是,通过service不断地和硬件设备交互,获取数据,在页面长时间停留在一个页面时,手机的屏幕会出项锁屏的状况,这时,我们的应用的优先级就会下降,很多次,等打开屏幕的瞬间,我发现原来的原来的进程被杀死了,应用又回到了首页,尤其是在Android高版本的系统中尤为突出。所以下面我们通过提成优先级的方式,来进行进程保活

2.在程序开始的地方注册这个广播接收者

4.定义这个activity的style属性 value - style.xml 文件

5.Androidmanifest文件中注册这个activity

大功告成!
经过测试,本人的华为荣耀9i,原来存在的问题被解决了,希望大家能互相交流经验。

C. 安卓开发线程和进程讲解


本教程为大家介绍安卓开发中的线程和进程,安卓平台中当首次启动运行一个组件的时候,Android会相应的启动了一个进程。默认的,所有的组件和程序运行在这个进程和线程中,也可以安排组件在其他的进程或者线程中运行。
进程:组件运行的进程由manifest file控制。组件的节点activity, service, receiver, 和 provider 都包含一个 process 属性。这个属性可以设置组件运行的进程:可以配置组件在一个独立进程运行,或者多个组件在同一个进程运行。甚至可以多个程序在一个进程中运行——如果这些程序共享一个User ID并给定同样的权限。 节点也包含 process 属性,用来设置程序中所有组件的默认进程。
所有的组件在此进程的主线程中实例化,系统对这些组件的调用从主线程中分离。并非每个对象都会从主线程中分离。一般来说,响应例如View.onKeyDown()用户操作的方法和通知的方法也在主线程中运行。这就表示,组件被系统调用的时候不应该长时间运行或者阻塞操作(如网络操作或者计算大量数据),因为这样会阻塞进程中的其他组件。可以把这类操作从主线程中分离。
当更加常用的进程无法获取足够内存,Android可能会关闭不常用的进程。下次启动程序的时候会重新启动进程。
当决定哪个进程需要被关闭的时候, Android会考虑哪个对用户更加有用。如Android会倾向于关闭一个长期不显示在界面的旦颂歼进程来支持一个经常显示在界面的进程。
线程:即使为组件分配了不同的进程,有时候也需要再分配线程。比如用户界面需要很快对用户进行响应,因此某些费时的操作,如网络连接、下载或者非常占用服务器时间的操作应该放到其他线程。
线程通过java的标准对象Thread 创建. Android 提供了很多方便的管理线程的方法:— Looper 在线程中运行一个消息循环; Handler 传递一个消息; HandlerThread 创建一个带有消息循环的线程。
远程调用Remote procere calls
Android有一个远程调用(RPCs) 的轻量级机制— 通过这个机制,方法可以在本地调用,在远程执行(在其他进程执行),还可以返回一个值。要实现这个需求,必须分解方法调用,并且所有要传递的数据必须是操作系统可以访问的级别。从本地的进程和内存地址传送到远程的进程和内存地樱正址并在远程处理和返回。返回值必须向相反的方向传递。Android提供了做以上操作的代码,所以开发者可以专注于实现RPC的接口。
一个RPC接口只能包含方法。所有的方法都是同步执行的(直到远程方法返回,本地方法才结束阻塞),没有返回值的时候也是如此。
简单来说,这个机制是这样的:使用IDL (interface definition language)定义你想要实现的接口, aidl 工具可以生成用于java的接口定义,本地和远程都要使用这个定义。它包含2个类,
inner类包含了所有的管理远程程序(符合IDL描述的接口)所需要的代码。所有的inner类实现了IBinder 接口.其中一个在本地使用,可以不管它的代码;另外一个叫做Stub继承了 Binder 类。为了实现远程调用,这个类包含RPC接口。开发者可以继承Stub类来实现需要的方法。
一般来说,远程进程会被一个service管理(因为service可以通知操作系统这个进程的信息并和其他进程通信),它也会包含aidl 工具产生的接口文件,Stub类实现了远处那个方法。服务的客户端只需要aidl 工具产生的接口文件。
以下是如何连接服务和客户端调用:
·服务的客户端(本地)会实现onServiceConnected() 和onServiceDisconnected() 方法,这样,当客户端连接或者断开连接的时候可以获取到通知。通过 bindService() 获取到服务的连接。
· 服务的 onBind() 方法中可以接收或者拒绝连接,取决它收到的intent (intent通过 bindService()方法连接到服务). 如果服务接收了连接,会返回一个Stub类的实例.
· 如果服务接受了连接,Android会调用客户端的onServiceConnected() 方法,模冲并传递一个Ibinder对象(系统管理的Stub类的代理),通过这个代理,客户端可以连接远程的服务。
以上的描述省略很多RPC的机制。请参见Designing a Remote Interface Using AIDL 和 IBinder 类。
线程安全的方法
在某些情况下,方法可能调用不止一个的线程,因此需要注意方法的线程安全。
对于可以远程调用的方法,也要注意这点。当一个调用在Ibinder对象中的方法的程序启动了和Ibinder对象相同的进程,方法就在Ibinder的进程中执行。但是,如果调用者发起另外一个进程,方法在另外一个线程中运行,这个线程在和IBinder对象在一个线程池中;它不会在进程的主线程中运行。例如,一个service从主线程被调用onBind() 方法,onBind() 返回的对象(如实现了RPC的Stub子类)中的方法会被从线程池中调用。因为一个服务可能有多个客户端请求,不止一个线程池会在同一时间调用IBinder的方法。因此IBinder必须线程安全。
简单来说,这个机制是这样的:使用IDL (interface definition language)定义你想要实现的接口, aidl 工具可以生成用于java的接口定义,本地和远程都要使用这个定义。它包含2个类,
inner类包含了所有的管理远程程序(符合IDL描述的接口)所需要的代码。所有的inner类实现了IBinder 接口.其中一个在本地使用,可以不管它的代码;另外一个叫做Stub继承了 Binder 类。为了实现远程调用,这个类包含RPC接口。开发者可以继承Stub类来实现需要的方法。
一般来说,远程进程会被一个service管理(因为service可以通知操作系统这个进程的信息并和其他进程通信),它也会包含aidl 工具产生的接口文件,Stub类实现了远处那个方法。服务的客户端只需要aidl 工具产生的接口文件。
以下是如何连接服务和客户端调用:
·服务的客户端(本地)会实现onServiceConnected() 和onServiceDisconnected() 方法,这样,当客户端连接或者断开连接的时候可以获取到通知。通过 bindService() 获取到服务的连接。
· 服务的 onBind() 方法中可以接收或者拒绝连接,取决它收到的intent (intent通过 bindService()方法连接到服务). 如果服务接收了连接,会返回一个Stub类的实例.
· 如果服务接受了连接,Android会调用客户端的onServiceConnected() 方法,并传递一个Ibinder对象(系统管理的Stub类的代理),通过这个代理,客户端可以连接远程的服务。
线程安全的方法
在某些情况下,方法可能调用不止一个的线程,因此需要注意方法的线程安全。
对于可以远程调用的方法,也要注意这点。当一个调用在Ibinder对象中的方法的程序启动了和Ibinder对象相同的进程,方法就在Ibinder的进程中执行。但是,如果调用者发起另外一个进程,方法在另外一个线程中运行,这个线程在和IBinder对象在一个线程池中;它不会在进程的主线程中运行。例如,一个service从主线程被调用onBind() 方法,onBind() 返回的对象(如实现了RPC的Stub子类)中的方法会被从线程池中调用。因为一个服务可能有多个客户端请求,不止一个线程池会在同一时间调用IBinder的方法。因此IBinder必须线程安全。
简单来说,一个content provider 可以接收其他进程的数据请求。即使ContentResolver和ContentProvider类没有隐藏了管理交互的细节,ContentProvider中响应这些请求的方法(query(), insert(), delete(), update(), and getType() )— 是在content provider的线程池中被调用的,而不是ContentProvider的本身进程。因为这些方法可能是同时从很多线程池运行的,所以这些方法必须要线程安全。

D. Android 守护进程的实现方式

在我们进行应用开发时,会遇到上级的各种需求,其中有一条 刚需: 后台保活 ,更有甚者:

我要我们的应用永远活在用户的手机后台不被杀死 —— 这都 TM 的扯淡

除了系统级别的应用能持续运行,所有三方程序都有被杀死的那一天!当然 QQ/微信/陌陌 等会好一些,因为他们已经深入设备的 心 ;
我们能做的只是通过各种手段尽量让我们的程序在后台运行的时间长一些,或者在被干掉的时候,能够重新站起来,而且这个也不是每次都有效的,也是不能在所有的设备的上都有效的;要做到后台进程保活,我们需要做到两方便:

要实现实现上边所说,通过下边几点来实现,首先我们需要了解下进程的优先级划分:

Process Importance 记录在 ActivityManager.java 类中:

了解进程优先级之后,我们还需要知道一个进程回收机制的东西;这里参考 AngelDevil 在博客园上的一篇文章:

Android 的 Low Memory Killer 基于 Linux 的 OOM 机制,在 Linux 中,内存是以页面为单位分配的,当申请页面分配时如果内存不足会通过以下流程选择bad进程来杀掉从而释放内存:

在 Low Memory Killer 中通过进程的 oom_adj 与占用内存的大小决定要杀死的进程, oom_adj 越小越不容易被杀死;
Low Memory Killer Driver 在用户空间指定了一组内存临界值及与之一一对应的一组 oom_adj 值,当系统剩余内存位于内存临界值中的一个范围内时,如果一个进程的 oom_adj 值大于或等于这个临界值对应的 oom_adj 值就会被杀掉。

下边是表示 Process State (即老版本里的 OOM_ADJ )数值对照表,数值越大,重要性越低,在新版SDK中已经在 android 层去除了小于0的进程状态

Process State (即老版本的 OOM_ADJ )与 Process Importance 对应关系,这个方法也是在 ActivityManager.java 类中,有了这个关系,就知道可以知道我们的应用处于哪个级别,对于我们后边优化有个很好地参考

一般情况下,设备端进程被干掉有一下几种情况

由以上分析,我们可以可以总结出,如果想提高我们应用后台运行时间,就需要提高当前应用进程优先级,来减少被杀死的概率

分析了那么多,现在对Android自身后台进程管理,以及进程的回收也有了一个大致的了解,后边我们要做的就是想尽一切办法去提高应用进程优先级,降低进程被杀的概率;或者是在被杀死后能够重新启动后台守护进程

第一种方式就是利用系统漏洞,使用 startForeground() 将当前进程伪装成前台进程,将进程优先级提高到最高(这里所说的最高是服务所能达到的最高,即1);

这种方式在 7.x 之前都是很好用的,QQ、微信、IReader、Keep 等好多应用都是用的这种方式实现;因为在7.x 以后的设备上,这种伪装前台进程的方式也会显示出来通知栏提醒,这个是取消不掉的,虽然 Google 现在还没有对这种方式加以限制,不过这个已经能够被用户感知到了,这种方式估计也用不了多久了

下边看下实现方式,这边这个 VMDaemonService 就是一个守护进程服务,其中在服务的 onStartCommand() 方法中调用 startForeground() 将服务进程设置为前台进程,当运行在 API18 以下的设备是可以直接设置,API18 以上需要实现一个内部的 Service ,这个内部类实现和外部类同样的操作,然后结束自己;当这个服务启动后就会创建一个定时器去发送广播,当我们的核心服务被干掉后,就由另外的广播接收器去接收我们守护进程发出的广播,然后唤醒我们的核心服务;

当我们启动这个守护进程的时候,就可以使用以下 adb 命令查看当前程序的进程情况(需要 adb shell 进去设备),
为了等下区分进程优先级,我启动了一个普通的后台进程,两外两个一个是我们启动的守护进程,一个是当前程序的核心进程,可以看到除了后台进程外,另外两个进程都带有 isForeground=true 的属性:

然后我们可以用下边的命令查看 ProcessID

有了 ProcessID 之后,我们可以根据这个 ProcessID 获取到当前进程的优先级状态 Process State ,对应 Linux 层的 oom_adj
可以看到当前核心进程的级别为 0 ,因为这个表示当前程序运行在前台 UI 界面,守护进程级别为 1 ,因为我们利用漏洞设置成了前台进程,虽然不可见,但是他的级别也是比较高的,仅次于前台 UI 进程,然后普通后台进程级别为 4 ;当我们退到后台时,可以看到核心进程的级别变为 1 了,这就是因为我们利用 startForeground() 将进程设置成前台进程的原因,这样就降低了进程被系统回收的概率了;

可以看到这种方式确实能够提高进程优先级,但是在一些国产的设备上还是会被杀死的,比我我测试的时候小米点击清空最近运行的应用进程就别干掉了;当把应用加入到设备白名单里就不会被杀死了,微信就是这样,人家直接装上之后就已经在白名单里了,我们要做的就是在用户使用中引导他们将我们的程序设置进白名单,将守护进程和白名单结合起来,这样才能保证我们的应用持续或者

Android系统在5.x以上版本提供了一个 JobSchele 接口,系统会根据自己实现定时去调用改接口传递的进程去实现一些操作,而且这个接口在被强制停止后依然能够正常的启动;不过在一些国产设备上可能无效,比如小米;
下边是 JobServcie 的实现:

我们要做的就是在需要的时候调用 JobSchele 的 schele 来启动任务;剩下的就不需要关心了, JobSchele 会帮我们做好,下边就是我这边实现的启动任务的方法:

在实现 Service 类时,将 onStartCommand() 返回值设置为 START_STICKY ,利用系统机制在 Service 挂掉后自动拉活;不过这种方式只适合比较原生一些的系统,像小米,华为等这些定制化比较高的第三方厂商,他们都已经把这些给限制掉了;

这种方式在以下两种情况无效:

事事没有绝对,万物总有一些漏洞,就算上边的那些方式不可用了,后边肯定还会出现其他的方式;我们不能保证我们的应用不死,但我们可以提高存活率;

其实最好的方式还是把程序做好,让程序本身深入人心,别人喜欢你了,就算你被干掉了,他们也会主动的把你拉起来,然后把你加入他们的白名单,然后我们的目的就实现了不是 😁 ~

E. 深入理解Android:SystemServer进程的作用

看了一段时间关于SystemServer进程的博客,有点小理解,写一篇关于SystemServer的小笔记,然后走一遍过程。

ZygoteInit通过startSystemServer方法fork了一个SS进程。这个进程有啥作用呢。

handlerSystemServerProcess()方法只要是以下三个方法:

其中 applicationInit() 很有意思很重要。该方法中有一个,invokeStaticMain方法通过反射调用main方法:

run方法最终通过反射调用SystemServer的main方法,作用是:
通过以上分析其实main方法的主要作用是:
1、调整系统时间
2、设置属性persist.sys.dalvik.vm.lib.2的值为当前虚拟机的运行库路径
3、装载libandroid_servers.so库,初始化native层service
4、初始化系统Context
5、创建SystemServiceManager对象
6、调用startBootstrapServices(),startCoreServices(),startOtherServices()启动所有的Java服务

另外也可以看到为什么说handler默认是主线程,以及android 应用本身就是基于handler/Looper/Message的
startBootstrapServices():启动java层的各种服务。framwork层的服务。例如AMS

startCoreServices:启动核心服务:

startOtherServices也与上面一样启动各种服务。

总结下:SystemServer进程最终会执行到SystemServer类中的main方法中,初始化各种服务器,其中第一个初始化的就是ActivityManagerService。当我们点击启动app的时候。Zygote会对这个消息进行处理,最终执行到applicationInit。那么是在哪里调用方法启动应用的呢?

热点内容
组合公式的算法 发布:2025-01-27 12:45:50 浏览:277
落樱小屋哪里下载安卓 发布:2025-01-27 12:35:13 浏览:71
微信服务器IP跳转 发布:2025-01-27 12:26:54 浏览:73
oracle自动备份脚本linux 发布:2025-01-27 12:21:40 浏览:936
pop服务器密码怎么填 发布:2025-01-27 12:20:02 浏览:968
oraclesqlnumber 发布:2025-01-27 12:04:22 浏览:849
如何看三才配置数理暗示力 发布:2025-01-27 12:04:15 浏览:811
我的世界离线2b2t的服务器 发布:2025-01-27 11:51:25 浏览:144
网站被异常篡改访问有风险 发布:2025-01-27 11:50:01 浏览:431
光遇国际服脚本全部图 发布:2025-01-27 11:47:40 浏览:139