当前位置:文档之家› Android系统在新进程中启动自定义服务过程(startService)的原理分析

Android系统在新进程中启动自定义服务过程(startService)的原理分析

Android系统在新进程中启动自定义服务过程(startService)的原理分析
Android系统在新进程中启动自定义服务过程(startService)的原理分析

Android系统在新进程中启动自定义服务过程(startService)的原理分析

在编写Android应用程序时,我们一般将一些计算型的逻辑放在一个独立的进程来处理,这样主进程仍然可以流畅地响应界面事件,提高用户体验。Android系统为我们提供了一个Service类,我们可以实现一个以Service为基类的服务子类,在里面实现自己的计算型逻辑,然后在主进程通过startService函数来启动这个服务。在本文中,将详细分析主进程是如何通过startService函数来在新进程中启动自定义服务的。

在主进程调用startService函数时,会通过Binder进程间通信机制来通知ActivitManagerService来创建新进程,并且启动指定的服务。在Android系统中,Binder进程间通信机制使用非常广泛,因此,希望读者在继续阅读下面的内容之前,对Android系统和Binder 进程间通信机制有一定的了解,具体可以参考前面Android进程间通信(IPC)机制Binder简要介绍和学习计划一文。

关于startService的具体用法,可以参考前面Android系统匿名共享内存Ashmem (Anonymous Shared Memory)简要介绍和学习计划一文中用到的实例,它是Activity类的一个成员函数:

view plain

1package shy.luo.ashmem;

2

3......

4

5public class Client extends Activity implements OnClickListener {

6 ......

7 IMemoryService memoryService = null;

8 ......

9

10 @Override

11public void onCreate(Bundle savedInstanceState) {

12 ......

13

14 IMemoryService ms = getMemoryService();

15if(ms == null) {

16 startService(new Intent("shy.luo.ashmem.server"));

17 } else {

18 Log.i(LOG_TAG, "Memory Service has started.");

19 }

20

21 ......

22

23 Log.i(LOG_TAG, "Client Activity Created.");

24 }

25

26 ......

27}

这里的“shy.luo.ashmem.server”是在程序配置文件AndroidManifest.xml配置的Service的名字,用来告诉Android系统它所要启动的服务的名字:

view plain

28

29package="shy.luo.ashmem"

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

31 android:versionCode="1"

32 android:versionName="1.0">

33

android:label="@string/app_name">

34 ......

35

36 android:enabled="true"

37 android:name=".Server"

38 android:process=".Server" >

39

40

41

android:name="android.intent.category.DEFAULT"/>

42

43

44

45

这里,名字“shy.luo.ashmem.server”对应的服务类为shy.luo.ashmem.Server,下面语句:

view plain

46startService(new Intent("shy.luo.ashmem.server"));

就表示要在一个新的进程中启动shy.luo.ashmem.Server这个服务类,它必须继承于Android平台提供的Service类:

view plain

47package shy.luo.ashmem;

48

49......

50

51public class Server extends Service {

52

53 ......

54

55 @Override

56public IBinder onBind(Intent intent) {

57return null;

58 }

59

60 @Override

61public void onCreate() {

62 ......

63

64 }

65

66 ......

67}

下面,我们来看看Activity类中的startService成员函数是如何实现的。

先来看看Activity的类图:

从图中可以看出,Activity继承了ContextWrapper类,而在ContextWrapper类中,实现了startService函数。在ContextWrapper类中,有一个成员变量mBase,它是一个ContextImpl实例,而ContextImpl类和ContextWrapper类一样继承于Context类,ContextWrapper类的startService函数最终过调用ContextImpl类的startService函数来实现。这种类设计方法在设计模式里面,就称之为装饰模式(Decorator),或者包装模式(Wrapper)。

在ContextImpl类的startService类,最终又调用了ActivityManagerProxy类的startService来实现启动服务的操作,看到这里的Proxy关键字,回忆一下前面Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析这篇文章,就会知道ActivityManagerProxy是一个Binder对象的远程接口了,而这个Binder对象就是我们前面所说的ActivityManagerService了。

这个ActivityManagerService类实现在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

文件中,它是Binder进程间通信机制中的Server角色,它是随机启动的。随机启动的Server是在frameworks/base/services/java/com/android/server/SystemServer.java文件里面进行启动的,我们来看一下ActivityManagerService启动相关的代码:

view plain

68class ServerThread extends Thread {

69

70 ......

71

72 @Override

73public void run() {

74

75 ......

76

77// Critical services...

78try {

79

80 ......

81

82 context = ActivityManagerService.main(factoryTest);

83

84 ......

85

86 ActivityManagerService.setSystemProcess();

87

88 ......

89

90 } catch (RuntimeException e) {

91 Slog.e("System", "Failure starting core service", e);

92 }

93

94 ......

95

96 }

97

98 ......

99

100}

首先是调用ActivityManagerService.main函数来创建一个ActivityManagerService 实例,然后通过调用ActivityManagerService.setSystemProcess函数把这个Binder实例添加Binder进程间通信机制的守护进程ServiceManager中去:

view plain

101public final class ActivityManagerService extends ActivityManagerNative 102implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 103

104 ......

105

106static ActivityManagerService mSelf;

107

108 ......

109

110public static void setSystemProcess() {

111try {

112 ActivityManagerService m = mSelf;

113

114 ServiceManager.addService("activity", m);

115

116 ......

117

118 } catch (https://www.doczj.com/doc/e19833302.html,NotFoundException e) {

119 ......

120 }

121 }

122

123 ......

124

125public static final Context main(int factoryTest) {

126

127 ......

128

129 ActivityManagerService m = thr.mService;

130 mSelf = m;

131

132 ......

133

134 }

135}

这样,ActivityManagerService就启动起来了。

回到ActivityManagerProxy类的startService函数中,它定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:

view plain

136class ActivityManagerProxy implements IActivityManager

137{

138 ......

139

140public ComponentName startService(IApplicationThread caller, Intent service,

141 String resolvedType) throws RemoteException

142 {

143 Parcel data = Parcel.obtain();

144 Parcel reply = Parcel.obtain();

145 data.writeInterfaceToken(IActivityManager.descriptor);

146 data.writeStrongBinder(caller != null ? caller.asBinder() : null);

147 service.writeToParcel(data, 0);

148 data.writeString(resolvedType);

149 mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);

150 reply.readException();

151 ComponentName res = ComponentName.readFromParcel(reply);

152 data.recycle();

153 reply.recycle();

154return res;

155 }

156

157 ......

158}

参数service是一个Intent实例,它里面指定了要启动的服务的名称,就是前面我们所说的“shy.luo.ashmem.server”了。

参数caller是一个IApplicationThread实例,它是一个在主进程创建的一个Binder对象。在Android应用程序中,每一个进程都用一个ActivityThread实例来表示,而在ActivityThread 类中,有一个成员变量mAppThread,它是一个ApplicationThread实例,实现了IApplicationThread接口,它的作用是用来辅助ActivityThread类来执行一些操作,这个我们在后面会看到它是如何用来启动服务的。

参数resolvedType是一个字符串,它表示service这个Intent的MIME类型,它是在解析Intent时用到的。在这个例子中,我们没有指定这个Intent 的MIME类型,因此,这个参数为null。

ActivityManagerProxy类的startService函数把这三个参数写入到data本地变量去,接着通过mRemote.transact函数进入到Binder驱动程序,然后Binder驱动程序唤醒正在等待Client请求的ActivityManagerService进程,最后进入到ActivityManagerService的startService函数中。

ActivityManagerService的startService函数的处理流程如下图所示:

点击查看大图

在这个序列图中,一共有20个步骤,下面说明每一步。

Step 1. ActivityManagerService.startService

这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java 文件中:

view plain

159public final class ActivityManagerService extends ActivityManagerNative 160implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

161

162 ......

163

164public ComponentName startService(IApplicationThread caller, Intent service,

165 String resolvedType) {

166// Refuse possible leaked file descriptors

167if (service != null && service.hasFileDescriptors() == true) { 168throw new IllegalArgumentException("File descriptors passed in Intent");

169 }

170

171synchronized(this) {

172final int callingPid = Binder.getCallingPid();

173final int callingUid = Binder.getCallingUid();

174final long origId = Binder.clearCallingIdentity();

175 ComponentName res = startServiceLocked(caller, service,

176 resolvedType, callingPid, callingUid);

177 Binder.restoreCallingIdentity(origId);

178return res;

179 }

180 }

181

182 ......

183

184}

这里的参数caller、service和resolvedType分别对应ActivityManagerProxy.startService传进来的三个参数。

Step 2. ActivityManagerService.startServiceLocked

这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

文件中:

view plain

185public final class ActivityManagerService extends ActivityManagerNative 186implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

187

188 ......

189

190 ComponentName startServiceLocked(IApplicationThread caller,

191 Intent service, String resolvedType,

192int callingPid, int callingUid) {

193synchronized(this) {

194 ......

195

196 ServiceLookupResult res =

197 retrieveServiceLocked(service, resolvedType,

198 callingPid, callingUid);

199

200 ......

201

202 ServiceRecord r = res.record;

203

204 ......

205

206if (!bringUpServiceLocked(r, service.getFlags(), false)) {

207return new ComponentName("!", "Service process is bad");

208 }

209return https://www.doczj.com/doc/e19833302.html,;

210 }

211 }

212

213 ......

214

215}

函数首先通过retrieveServiceLocked来解析service这个Intent,就是解析前面我们在AndroidManifest.xml定义的Service标签的intent-filter相关内容,然后将解析结果放在res.record中,然后继续调用bringUpServiceLocked进一步处理。

Step 3. ActivityManagerService.bringUpServiceLocked

这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

文件中:

view plain

216public final class ActivityManagerService extends ActivityManagerNative 217implements Watchdog.Monitor,

BatteryStatsImpl.BatteryCallback {

218

219 ......

220

221private final boolean bringUpServiceLocked(ServiceRecord r,

222int intentFlags, boolean whileRestarting) {

223

224 ......

225

226final String appName = r.processName;

227

228 ......

229

230// Not running -- get it started, and enqueue this service record

231// to be executed when the app comes up.

232if (startProcessLocked(appName, r.appInfo, true, intentFlags,

233"service", https://www.doczj.com/doc/e19833302.html,, false) == null) {

234

235 ......

236

237return false;

238 }

239

240if (!mPendingServices.contains(r)) {

241 mPendingServices.add(r);

242 }

243

244return true;

245

246 }

247

248 ......

249

250}

这里的appName便是我们前面在AndroidManifest.xml文件定义service标签时指定的android:process属性值了,即“.Server”。

接着调用startProcessLocked函数来创建一个新的进程,以便加载自定义的Service类。最后将这个ServiceRecord保存在成员变量mPendingServices列表中,后面会用到。

Step 4. ActivityManagerService.startProcessLocked

这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

文件中:

view plain

251public final class ActivityManagerService extends ActivityManagerNative 252implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

253

254 ......

255

256private final void startProcessLocked(ProcessRecord app,

257 String hostingType, String hostingNameStr) {

258

259 ......

260

261try {

262

263 ......

264

265int pid = Process.start("android.app.ActivityThread",

266 mSimpleProcessManagement ? app.processName : null, uid, uid,

267 gids, debugFlags, null);

268

269 ......

270

271if (pid == 0 || pid == MY_PID) {

272

273 ......

274

275 } else if (pid > 0) {

276 app.pid = pid;

277 app.removed = false;

278synchronized (mPidsSelfLocked) {

279this.mPidsSelfLocked.put(pid, app);

280 ......

281 }

282 } else {

283

284 ......

285 }

286

287 } catch (RuntimeException e) {

288

289 ......

290

291 }

292

293 }

294

295 ......

296

297}

这里调用Process.start函数创建了一个新的进程,指定新的进程执行android.app.ActivityThread类。最后将表示这个新进程的ProcessRecord保存在mPidSelfLocked列表中,后面会用到。

Step 5. Process.start

这个函数定义在frameworks/base/core/java/android/os/Process.java文件中,这个函数我们就不看了,有兴趣的读者可以自己研究一下。在这个场景中,它就是新建一个进程,然后导入android.app.ActivityThread这个类,然后执行它的main函数。

Step 6. ActivityThread.main

这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

view plain

298public final class ActivityThread {

299

300 ......

301

302public static final void main(String[] args) {

303

304 ......

305

306 Looper.prepareMainLooper();

307

308 ......

309

310 ActivityThread thread = new ActivityThread();

311 thread.attach(false);

312

313 ......

314

315 Looper.loop();

316

317 ......

318

319 thread.detach();

320

321 ......

322 }

323}

注意,执行到这里的时候,已经是在上一步创建的新进程里面了,即这里的进程是用来启动服务的,原来的主进程已经完成了它的命令,返回了。

前面我们提到,在Android应用程序中,每一个进程对应一个ActivityThread实例,所以,这个函数会创建一个thread实例,然后调用ActivityThread.attach函数进一步处理。

Step 7. ActivityThread.attach

这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

view plain

324public final class ActivityThread {

325

326 ......

327

328private final void attach(boolean system) {

329

330 ......

331

332if (!system) {

333

334 ......

335

336 IActivityManager mgr = ActivityManagerNative.getDefault();

337try {

338 mgr.attachApplication(mAppThread);

339 } catch (RemoteException ex) {

340 }

341 } else {

342

343 ......

344

345 }

346

347 ......

348

349 }

350

351 ......

352

353}

从Step 6中,这里传进来的参数system为false。成员变量mAppThread是一个ApplicationThread实例,我们在前面已经描述过这个实例的作用,它是用来辅助ActivityThread 来执行一些操作的。

调用ActivityManagerNative.getDefault函数得到ActivityManagerService的远程接口,即ActivityManagerProxy,接着调用它的attachApplication函数。

Step 8. ActivityManagerProxy.attachApplication

这个函数定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:

view plain

354class ActivityManagerProxy implements IActivityManager

355{

356 ......

357

358public void attachApplication(IApplicationThread app) throws RemoteException

359 {

360 Parcel data = Parcel.obtain();

361 Parcel reply = Parcel.obtain();

362 data.writeInterfaceToken(IActivityManager.descriptor);

363 data.writeStrongBinder(app.asBinder());

364 mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);

365 reply.readException();

366 data.recycle();

367 reply.recycle();

368 }

369

370 ......

371

372}

这个函数主要是将新进程里面的IApplicationThread实例通过Binder驱动程序传递给ActivityManagerService。

Step 9. ActivityManagerService.attachApplication

这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

文件中:

view plain

373public final class ActivityManagerService extends ActivityManagerNative 374implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

375

376 ......

377

378public final void attachApplication(IApplicationThread thread)

379 {

380synchronized (this) {

381int callingPid = Binder.getCallingPid();

382final long origId = Binder.clearCallingIdentity();

383 attachApplicationLocked(thread, callingPid);

384 Binder.restoreCallingIdentity(origId);

385 }

386 }

387

388 ......

389

390}

这里通过调用attachApplicationLocked函数进一步处理。

Step 10. ActivityManagerService.attachApplicationLocked

这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

文件中:

view plain

391public final class ActivityManagerService extends ActivityManagerNative 392implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

393

394 ......

395

396private final boolean attachApplicationLocked(IApplicationThread thread, 397int pid) {

398// Find the application record that is being attached... either via 399// the pid if we are running in multiple processes, or just pull the 400// next app record if we are emulating process with anonymous threads.

401 ProcessRecord app;

402if (pid != MY_PID && pid >= 0) {

403synchronized (mPidsSelfLocked) {

404 app = mPidsSelfLocked.get(pid);

405 }

406 } else if (mStartingProcesses.size() > 0) {

407 app = mStartingProcesses.remove(0);

408 app.setPid(pid);

409 } else {

410 app = null;

411 }

412

413 ......

414

415

416 String processName = app.processName;

417

418 ......

419

420 app.thread = thread;

421

422 ......

423

424boolean badApp = false;

425

426 ......

427

428// Find any services that should be running in this process...

429if (!badApp && mPendingServices.size() > 0) {

430 ServiceRecord sr = null;

431try {

432for (int i=0; i

433 sr = mPendingServices.get(i);

434if (https://www.doczj.com/doc/e19833302.html,.uid != sr.appInfo.uid

435 || !processName.equals(sr.processName)) {

436continue;

437 }

438

439 mPendingServices.remove(i);

440 i--;

441 realStartServiceLocked(sr, app);

442 didSomething = true;

443 }

444 } catch (Exception e) {

445

446 ......

447

448 }

449 }

450

451 ......

452

453return true;

454 }

455

456 ......

457

458}

回忆一下在上面的Step 4中,以新进程的pid值作为key值保存了一个ProcessRecord 在mPidsSelfLocked列表中,这里先把它取出来,存放在本地变量app中,并且将app.processName保存在本地变量processName中。

再回忆一下在上面的Step 3中,在成员变量mPendingServices中,保存了一个ServiceRecord,这里通过进程uid和进程名称将它找出来,然后通过realStartServiceLocked 函数来进一步处理。

Step 11. ActivityManagerService.realStartServiceLocked

这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java 文件中:

view plain

459class ActivityManagerProxy implements IActivityManager

460{

461 ......

462

463private final void realStartServiceLocked(ServiceRecord r,

464 ProcessRecord app) throws RemoteException {

465

466 ......

467

468 r.app = app;

469

470 ......

471

472try {

473

474 ......

475

476 app.thread.scheduleCreateService(r, r.serviceInfo);

477

478 ......

479

480 } finally {

481

482 ......

483

484 }

485

486 ......

487

488 }

489

490 ......

491

492}

这里的app.thread是一个ApplicationThread对象的远程接口,它是在上面的Step 6创建ActivityThread对象时作为ActivityThread对象的成员变量同时创建的,然后在Step 9中传过来的。然后调用这个远程接口的scheduleCreateService函数回到原来的ActivityThread对象中执行启动服务的操作。

Step 12. ApplicationThreadProxy.scheduleCreateService

这个函数定义在

frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中:

view plain

493class ApplicationThreadProxy implements IApplicationThread {

494

495 ......

496

497public final void scheduleCreateService(IBinder token, ServiceInfo info) 498throws RemoteException {

499 Parcel data = Parcel.obtain();

500 data.writeInterfaceToken(IApplicationThread.descriptor);

501 data.writeStrongBinder(token);

502 info.writeToParcel(data, 0);

503 mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null, 504 IBinder.FLAG_ONEWAY);

505 data.recycle();

506 }

507

508 ......

509

510}

这里通过Binder驱动程序回到新进程的ApplicationThread对象中去执行scheduleCreateService函数。

Step 13. ApplicationThread.scheduleCreateService

这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

view plain

511public final class ActivityThread {

512

513 ......

514

515private final class ApplicationThread extends ApplicationThreadNative { 516

517 ......

518

519public final void scheduleCreateService(IBinder token,

520 ServiceInfo info) {

521 CreateServiceData s = new CreateServiceData();

522 s.token = token;

分析Android 开机启动慢的原因

开机启动花了40多秒,正常开机只需要28秒就能开机起来。 内核的启动我没有去分析,另一个同事分析的。我主要是分析从SystemServer启来到开机动画结束显示解锁界面的这段时间,也就是开机动画的第三个动画开始到结束这段时间,这是个比较耗时阶段,一般都在17秒左右(见过牛B的手机,只需5秒)。 SystemServer分两步执行:init1和init2。init1主要是初始化native的服务,代码在sy stem_init.cpp的system_init,初始化了SurfaceFlinger和SensorService这两个native的服务。init2启动的是java的服务,比如ActivityManagerService、WindowManagerService、PackageManagerService等,在这个过程中PackageManagerService用的时间最长,因为PackageManagerService会去扫描特定目录下的jar包和apk文件。 在开机时间需要40多秒的时,从Log上可以看到,从SurfaceFlinger初始化到动画结束,要27秒左右的时间,即从SurfaceFlinger::init的LOGI("SurfaceFlinger is starting")这句Log到void SurfaceFlinger::bootFinished()的LOGI("Boot is finished (%ld ms)", long(ns 2ms(duration)) ),需要27秒左右的时间,这显然是太长了,但到底是慢在哪了呢?应该在个中间的点,二分一下,于是想到了以启动服务前后作为分隔:是服务启动慢了,还是在服务启动后的这段时间慢?以ActivityManagerService的Slog.i(TAG, "System now ready")的这句Log为分割点,对比了一下,在从SurfaceFlinger is starting到System now read y多了7秒左右的时间,这说明SystemServer在init1和init2过程中启动慢了,通过排查,发现在init1启动的时候,花了7秒多的时间,也就是system_init的LOGI("Entered system _init()")到LOGI("System server: starting Android runtime.\n")这段时间用了7秒多,而正常情况是400毫秒便可以初始化完,通过添加Log看到,在SensorService启动时,用了比较长的时间。 不断的添加Log发现,在启动SensorService时候,关闭设备文件变慢了,每次关闭一个/dev/input/下的设备文件需要100ms左右,而SensorService有60~70次的关闭文件,大概有7s左右的时间。 调用流程是: frameworks/base/cmds/system_server/library/system_init.cpp: system_init->SensorServi ce::instantiate frameworks/native/services/sensorservice/SensorService.cpp: void SensorService::onFi rstRef()->SensorDevice& dev(SensorDevice::getInstance()) hardware/libsensors/SensorDevice.cpp: SensorDevice::SensorDevice()->sensors_open hardware/libsensors/sensors.cpp: open_sensors->sensors_poll_context_t sensors_poll_context_t执行打开每个传感器设备时,遍历/dev/input/目录下的设备文件,以匹配当前需要打开的设备,遍历文件是在 hardware/libsensors/SensorBase.cpp的openInput下实现,如果打开的设备文件不是正在打开的设备文件,会执行下面语句的else部分: if (!strcmp(name, inputName)) { strcpy(input_name, filename); break;

Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析

在前面几篇文章中,我们详细介绍了Android系统进程间通信机制Binder的原理,并且深入分析了系统提供的Binder运行库和驱动程序的源代码。细心的读者会发现,这几篇文章分析的Binder接口都是基于C/C++语言来实现的,但是我们在编写应用程序都是基于Java语言的,那么,我们如何使用Java语言来使用系统的Binder机制来进行进程间通信呢?这就是本文要介绍的Android系统应用程序框架层的用Java语言来实现的Binder接口了。 熟悉Android系统的读者,应该能想到应用程序框架中的基于Java语言的Binder接口是通过JNI来调用基于C/C++语言的Binder运行库来为Java应用程序提供进程间通信服务的了。JNI在Android系统中用得相当普遍,SDK中的Java 接口API很多只是简单地通过JNI来调用底层的C/C++运行库从而为应用程序服务的。 这里,我们仍然是通过具体的例子来说明Binder机制在应用程序框架层中的Java接口,主要就是Service Manager、Server和Client这三个角色的实现了。通常,在应用程序中,我们都是把Server实现为Service的形式,并且通过IServiceManager.addService接口来把这个Service添加到Service Manager,Client也是通过IServiceManager.getService接口来获得Service接口,接着就可以使用这个Service提供的功能了,这个与运行时库的Binder接口是一致的。 前面我们学习Android硬件抽象层时,曾经在应用程序框架层中提供了一个硬件访问服务HelloService,这个Service运行在一个独立的进程中充当Server的角色,使用这个Service的Client运行在另一个进程中,它们之间就是通过Binder机制来通信的了。这里,我们就使用HelloService这个例子来分析Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码。所以希望读者在阅读下面的内容之前,先了解一下前面在Ubuntu上为Android系统的Application Frameworks层增加硬件访问服务这篇文章。 这篇文章通过五个情景来学习Android系统进程间通信Binder机制在应用程序框架层的Java接口:1. 获取Service Manager的Java远程接口的过程;2. HelloService接口的定义;3. HelloService的启动过程;4. Client获取HelloService 的Java远程接口的过程;5. Client通过HelloService的Java远程接口来使用HelloService提供的服务的过程。 一. 获取Service Manager的Java远程接口

Android系统精简列表对照表

安卓系统精简列表对照表,适用于大部分Android系统,大家请参考对照精简。AirkanPhoneService 可删 AntiSpam 可删 AdupsFot.apk无线升级(可删) AdupsFotaReboot.apk重启升级操作(可删) ApplicationGuide.apk-应用程度指南(不可删)ApplicationsProvider.apk-应用程序存储服务(不可删) AtciService.apk--系统服务(不可删) Backup.apk 可删 BackupRestoreConfirmation.apkGoogle邮箱的备份,可删BasicDreams.apk 4.2新增,休眠模式,不可删 BatteryWarning.apk--电池警告(建议保留) Browser.apk-谷歌浏览器(可删) BugReport 可删 Calculator.apk---计算器(可删) Calendar.apk日历(可删,换第三方日历) CalendarImporter.apk日历服务(同上) CalendarProvider.apk-日历存储(同上) CDS_INFO.apk--常见数据服务(不可删) CellBroadcastReceiver.apk小区广播(可删) CellConnService.apk---电话连接服务(不可删) CertInstaller.apk-证书安装,可删(亲测,没发现问题)

Cit可删 CloudService可删 ChromeBookmarksSyncAdapter.apk-Google书签同步(可删) com.google.android.apps.docs.apk--云端硬盘(可删) com.google.android.apps.maps.apk-谷歌地图(可删) com.google.android.googlequicksearchbox.apk-Google搜索(可删) com.google.android.street.apk--街景视图(可删) Contacts.apk--通讯录/联系人(不可删) ContactsProvider.apk--通讯录/联系人数据存储服务(不可删)DataHubProvider.apk. 会导致流量红圈不可删 DataTransfer.apk-备份与恢复(可删) DataUsageLockScreenClient.apk数据应用和锁定屏幕客户端(不可删)DefaultContainerService.apk-默认存储服务(不可删) DeskClock.apk闹钟,时钟(建议保留) DownloadProvider.apk 下载管理器,可删(删了就不能在谷歌电子市场和谷歌浏览器下载东西了,需要的留着) DownloadProviderUi.apk 下载内容,可删(同上) DrmProvider.apk 受DRM保护的内容的存储,可删(有DRM保护的东西就留着这个)Email.apk-电子邮件(可删) EngineerMode.apk--工程模式(不可删) EngineerModeSim.apksim卡工程模式(不可删) EventReceiver 翻译过来就是事件接收还是别删了这个网上没查到多少资料

基于MT6752的 android 系统启动流程分析报告

基于MT6752的Android系统启动流程分析报告 1、Bootloader引导 (2) 2、Linux内核启动 (23) 3、Android系统启动 (23) 报告人: 日期:2016.09.03

对于Android整个启动过程来说,基本可以划分成三个阶段:Bootloader引导、Linux kernel启动、Android启动。但根据芯片架构和平台的不同,在启动的Bootloader阶段会有所差异。 本文以MTK的MT6752平台为例,分析一下基于该平台的Android系统启动流程。 1、Bootloader引导 1.1、Bootloader基本介绍 BootLoader是在操作系统运行之前运行的一段程序,它可以将系统的软硬件环境带到一个合适状态,为运行操作系统做好准备,目的就是引导linux操作系统及Android框架(framework)。 它的主要功能包括设置处理器和内存的频率、调试信息端口、可引导的存储设备等等。在可执行环境创建好之后,接下来把software装载到内存并执行。除了装载software,一个外部工具也能和bootloader握手(handshake),可指示设备进入不同的操作模式,比如USB下载模式和META模式。就算没有外部工具的握手,通过外部任何组合或是客户自定义按键,bootloader也能够进入这些模式。 由于不同处理器芯片厂商对arm core的封装差异比较大,所以不同的arm处理器,对于上电引导都是由特定处理器芯片厂商自己开发的程序,这个上电引导程序通常比较简单,会初始化硬件,提供下载模式等,然后才会加载通常的bootloader。 下面是几个arm平台的bootloader方案: marvell(pxa935) : bootROM + OBM + BLOB informax(im9815) : bootROM + barbox + U-boot mediatek(mt6517) : bootROM + pre-loader + U-boot broadcom(bcm2157) : bootROM + boot1/boot2 + U-boot 而对MT6752平台,MTK对bootloader引导方案又进行了调整,它将bootloader分为以下两个部分: (1) 第1部分bootloader,是MTK内部(in-house)的pre-loader,这部分依赖平台。 (2) 第2部分bootloader,是LK(little kernel的缩写,作用同常见的u-boot差不多),这部分依赖操作系统,负责引导linux操作系统和Android框架。 1.2、bootloader的工作流程 1.2.1 bootloader正常的启动流程 先来看启动流程图:

Android 杀掉自己进程的方法

Android 杀掉自己进程的方法 Process.killProcess(Process.myPid()); 代码如下 protected void quit() { int size = activityManager.activityStackCount(); for(int i =size-1 ; i > 0 ;i--) { Activity activity = activityManager.allT askActivity().get(i); activityManager.popActivity(activity); } activityManager = null; getActivity().finish(); //目前最为通用的关闭进程的方法以后的版本使用 Intent startMain = new Intent(Intent.ACTION_MAIN); startMain.addCategory(Intent.CATEGORY_HOME); startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(startMain); android.os.Process.killProcess(android.os.Process.myPid()); } android.os.Process.killProcess(appProcessInfo.pid);只能杀死自己所创建的进程,其它进程是杀不掉的,要用到另外一个方法 activityManager.killBackgroundProcesses(processName);,同是权限也要加上 以下是我的测试代码 public class ListViewActivity extends Activity { /** Called when the activity is first created. */ private Button button; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

Android下Camera框架解析

Android 下Camera 构架分析 一. Android Camera 层次结构 Android 下Camera 子系统从上到下可以分为应用层、框架层、运行库层及内核层,其结构如下图所示。从整体上看,它还是属于Android 下典型的client/service 的结构,运行在两个进程中,一个是client 进程,主要包括JA V A 代码与一些Native c/c++代码;另一个是service 进程,属于服务端,是native c/c++代码,并且,camera service 属于Android 系统的一个native 服务,用native c/c++代码实现,主要负责和Linux kernel 中的Camera Driver 交互,搜集Linux kernel 中Camera Driver 上传的数据,并交给显示系统(surface)显示。 client 进程与service 进程通过Binder 机制通信,client 端通过调用service 端的接口实现各个具体的功能。但真正的preview 数据不会通过Binder IPC 机制从service 端复制到client 端,而是通过回调函数与消息的机制将preview 数据buffer 的地址传到client 端,最终可在Java 应用中操作处理这个preview 数据。 android_hardware.camera Camera Apps Libandroid_runtime.so (android_hardware_Camera.cpp) libcamera_client.so (Camara.cpp) 应用层框架层运行库层 硬件层 Libcamera.so (HAL)libcameraservice.so (CameraService.cpp)Linux 内核层 V4L2 Kernel Driver Camera Hardware BinderIPC JNI Client Service 二. Android Camera 的代码结构 1)应用层 Camera 的应用层在Android 上表现为直接调用SDK API 开发的一个

Android的系统服务一览

Android的系统服务一览 System_Server进程 运行在system server进程中的服务比较多,这是整个android框架的基础 Native服务 SurfaceFlinger 这是framebuffer合成的服务,将各个应用程序及应用程序中的逻辑窗口图像数据(surface)合成到一个物理窗口中显示(framebuffer)的服务程序 Java服务: 这部分的服务大部分都有一个供应用进程使用的manager类,这就是一个RPC 调用,用户通过调用xxxManager的方法,实际上被Binder给迁移到system_server 进程中对应的xxxManagerService中对应的方法,并将结果再通过binder带回。 1. EntropyService 熵服务,周期性的加载和保存随机信息。主要是linux开机后,/dev/random的状态可能是可预知的,这样一些需要随机信息的应用程序就可能会有问题。这个无需提供应用程序接口。 2. PowerManagerService –> PowerManager Android 的电源管理也是很重要的一部分。比如在待机的时候关掉不用的设备,待机时屏幕和键盘背光的关闭,用户操作的时候该打开多少设备等等。 3. ActivityManagerService->ActivityManager 这个是整个Android framework框架中最为核心的一个服务,管理整个框架中任务、进程管理, Intent解析等的核心实现。虽然名为Activity的Manager

Service,但它管辖的范围,不只是Activity,还有其他三大组件,和它们所在的进程。也就是说用户应用程序的生命管理,都是由他负责的。 4. TelephonyRegistry->TelephonyManager 电话注册、管理服务模块,可以获取电话的链接状态、信号强度等等。<可以删掉,但要看的大概明白> 5. PackageManagerService -> PackageManager 包括对软件包的解包,验证,安装以及升级等等,对于我们现在不能安装.so文件的问题,应该先从这块着手分析原因。 6. AccountManagerService -> AccountManager A system service that provides account, password, and authtoken management for all accounts on the device。 7. ContentService -> ContentResolver 内容服务,主要是数据库等提供解决方法的服务。 8. BatteryService 监控电池充电及状态的服务,当状态改变时,会广播Intent 9. HardwareService 一般是ring和vibrate的服务程序 10. SensorService -> SensorManager 管理Sensor设备的服务,负责注册client设备及当client需要使用sensor时激活Sensor 11. WindowManagerService -> WindowManager -> PhoneWindowManager 和ActivityManagerService高度粘合 窗口管理,这里最核心的就是输入事件的分发和管理。 12. AlarmManagerService -> AlarmManager 闹钟服务程序

Android 开机启动流程

Android的开机流程 1. 系统引导bootloader 1) 源码:bootable/bootloader/* 2) 说明:加电后,CPU将先执行bootloader程序,此处有三种选择 a) 开机按Camera+Power启动到fastboot,即命令或SD卡烧写模式,不加载内核及文件系统,此处可以进行工厂模式的烧写 b) 开机按Home+Power启动到recovery模式,加载recovery.img,recovery.i mg包含内核,基本的文件系统,用于工程模式的烧写 c) 开机按Power,正常启动系统,加载boot.img,boot.img包含内核,基本文件系统,用于正常启动手机(以下只分析正常启动的情况) 2. 内核kernel 1) 源码:kernel/* 2) 说明:kernel由bootloader加载 3. 文件系统及应用init 1) 源码:system/core/init/* 2) 配置文件:system/rootdir/init.rc, 3) 说明:init是一个由内核启动的用户级进程,它按照init.rc中的设置执行:启动服务(这里的服务指linux底层服务,如adbd提供adb支持,vold提供SD卡挂载等),执行命令和按其中的配置语句执行相应功能 4. 重要的后台程序zygote 1)源码:frameworks/base/cmds/app_main.cpp等 2) 说明:zygote是一个在init.rc中被指定启动的服务,该服务对应的命令是/system/bin/app_process a)建立Java Runtime,建立虚拟机 b) 建立Socket接收ActivityManangerService的请求,用于Fork应用程序 c) 启动System Server 5. 系统服务system server 1)源码:frameworks/base/services/java/com/android/server/SystemServer.jav a 2) 说明:被zygote启动,通过SystemManager管理android的服务(这里的服务指frameworks/base/services下的服务,如卫星定位服务,剪切板服务等) 6. 桌面launcher 1)源码:ActivityManagerService.java为入口,packages/apps/launcher*实现 2) 说明:系统启动成功后SystemServer使用xxx.systemReady()通知各个服务,系统已经就绪,桌面程序Home就是在ActivityManagerService.systemReady()通知的过程中建立的,最终调用()启launcher 7. 解锁 1) 源码: frameworks/policies/base/phone/com/android/internal/policy/impl/*lock* 2) 说明:系统启动成功后SystemServer调用wm.systemReady()通知WindowManagerService,进而调用PhoneWindowManager,最终通过LockPatternKeyguardView显示解锁界面,跟踪代码可以看到解锁界面并不是一个Activity,这是只是向特定层上绘图,其代码了存放在特殊的位置

linux内核启动 Android系统启动过程详解

linux内核启动+Android系统启动过程详解 第一部分:汇编部分 Linux启动之 linux-rk3288-tchip/kernel/arch/arm/boot/compressed/ head.S分析这段代码是linux boot后执行的第一个程序,完成的主要工作是解压内核,然后跳转到相关执行地址。这部分代码在做驱动开发时不需要改动,但分析其执行流程对是理解android的第一步 开头有一段宏定义这是gnu arm汇编的宏定义。关于GUN 的汇编和其他编译器,在指令语法上有很大差别,具体可查询相关GUN汇编语法了解 另外此段代码必须不能包括重定位部分。因为这时一开始必须要立即运行的。所谓重定位,比如当编译时某个文件用到外部符号是用动态链接库的方式,那么该文件生成的目标文件将包含重定位信息,在加载时需要重定位该符号,否则执行时将因找不到地址而出错 #ifdef DEBUG//开始是调试用,主要是一些打印输出函数,不用关心 #if defined(CONFIG_DEBUG_ICEDCC)

……具体代码略 #endif 宏定义结束之后定义了一个段, .section ".start", #alloc, #execinstr 这个段的段名是 .start,#alloc表示Section contains allocated data, #execinstr表示Section contains executable instructions. 生成最终映像时,这段代码会放在最开头 .align start: .type start,#function /*.type指定start这个符号是函数类型*/ .rept 8 mov r0, r0 //将此命令重复8次,相当于nop,这里是为中断向量保存空间 .endr b 1f .word 0x016f2818 @ Magic numbers to help the loader

最新Android应用程序绑定服务bindService的过程源代码分析汇总

A n d r o i d应用程序绑定服务b i n d S e r v i c e 的过程源代码分析

Android应用程序组件Service与Activity一样,既可以在新的进程中启动,也可以在应用程序进程内部启动;前面我们已经分析了在新的进程中启动Service的过程,本文将要介绍在应用程序内部绑定Service的过程,这是一种在应用程序进程内部启动Service的方法。 在前面一篇文章Android进程间通信(IPC)机制Binder简要介绍和学习计划中,我们就曾经提到,在Android系统中,每一个应用程序都是由一些Activity和Service组成的,一般Service运行在独立的进程中,而Activity有可能运行在同一个进程中,也有可能运行在不同的进程中;在接下来的文章中,Android系统在新进程中启动自定义服务过程(startService)的原理分析一文介绍了在新的进程中启动Service的过程,Android应用程序启动过程源代码分析一文介绍了在新的进程中启动Activity的过程,而Android应用程序内部启动Activity过程(startActivity)的源代码分析一文则介绍了在应用程序进程内部启动Activity的过程;本文接过最后一棒,继续介绍在应用程序进程内部启动Service的过程,这种过程又可以称在应用程序进程内部绑定服务(bindService)的过程,这样,读者应该就可以对Android应用程序启动Activity和Service有一个充分的认识了。 这里仍然是按照老规矩,通过具体的例子来分析Android应用程序绑定Service的过程,而所使用的例子便是前面我们在介绍Android系统广播机制的一篇文章Android系统中的广播(Broadcast)机制简要介绍和学习计划中所开发的应用程序Broadcast了。 我们先简单回顾一下这个应用程序实例绑定Service的过程。在这个应用程序的MainActivity的onCreate函数中,会调用bindService来绑定一个计数器服务CounterService,这里绑定的意思其实就是在MainActivity内部获得CounterService的接口,所以,这个过程的第一步就是要把CounterService 启动起来。当CounterService的onCreate函数被调用起来了,就说明CounterService已经启动起来了,接下来系统还要调用CounterService的onBind函数,跟CounterService要一个Binder对象,这个Binder对象是在CounterService内部自定义的CounterBinder类的一个实例,它继承于Binder类,里面实现一个getService函数,用来返回外部的CounterService接口。系统得到这个Binder对象之后,就会调用MainActivity在bindService函数里面传过来的ServiceConnection实例的onServiceConnected函数,并把这个Binder对象以参数的形式传到onServiceConnected函数里面,于是,MainActivity就可以调用这个Binder对象的getService函数来获得CounterService的接口了。 这个过程比较复杂,但总体来说,思路还是比较清晰的,整个调用过程为MainActivity.bindService->CounterService.onCreate->CounterService.onBind- >MainActivity.ServiceConnection.onServiceConnection->CounterService.CounterBinder.getService。下面,我们就先用一个序列图来总体描述这个服务绑定的过程,然后就具体分析每一个步骤。

Android开机启动流程样本

Android的开机流程 1. 系统引导bootloader 1) 源码: bootable/bootloader/* 2) 说明: 加电后, CPU将先执行bootloader程序, 此处有三种选择 a) 开机按Camera+Power启动到fastboot, 即命令或SD卡烧写模式, 不加载内核及文件系统, 此处能够进行工厂模式的烧写 b) 开机按Home+Power启动到recovery模式, 加载recovery.img, recovery.img包含内核, 基本的文件系统, 用于工程模式的烧写 c) 开机按Power, 正常启动系统, 加载boot.img, boot.img包含内核, 基本文件系统, 用于正常启动手机( 以下只分析正常启动的情况) 2. 内核kernel 1) 源码: kernel/* 2) 说明: kernel由bootloader加载 3. 文件系统及应用init 1) 源码: system/core/init/* 2) 配置文件: system/rootdir/init.rc, 3) 说明: init是一个由内核启动的用户级进程, 它按照init.rc中的设置执行: 启动服务( 这里的服务指linux底层服务, 如adbd提供adb支持, vold提供SD卡挂载等) , 执行命令和按其中的配置语句执行相应功能 4. 重要的后台程序zygote 1) 源码: frameworks/base/cmds/app_main.cpp等 2) 说明: zygote是一个在init.rc中被指定启动的服务, 该服务对应的命令是/system/bin/app_process

能够删除的安卓(Android)系统自带程序详细列表

能够删除的安卓(Android)系统自带程序详细列表 注:删除前请先备份 有机友因为删除了系统自带的一些程序,使得手机出现很大的问题,只有重新刷机才可以解决。这份表单,供各位在删除程序的时候做个参考。Android手机系统中默认会自带很多无用程序,这些应用,平时很少用不到,但因为是系统自带的,所以它们像牛皮癣一样内嵌在手机里,无法去除。下面列举一些能够删除和不能够删除的软件列表,希望对G友有用!怎么删除呢?当然是下载一个Root Explorer来删除(需要完全ROOT) 注意: 1. 有*号是绝不可删的,否则会出现严重问题; 2. 删除系统自带程序前,请注意备份; 3. 因不同版本的Android系统和不同品牌手机的定制,会有差异导致系统自带程序列表有差异,但大体上一致,请大家自己斟酌。 自带的软件列表: *AccountAndSyncSettings.apk 同步与帐户设定(绝不能删除) *ApplicationsProvider.apk 应用程序支持服务(绝不能删除)Bluetooth.apk 蓝牙(删除后蓝牙功能消失)Browser.apk 系统自带浏览器(可用其他手机浏览器替代) Calculator.apk 计算器(可删,可用其他替代)Calendar.apk 日历(可删) CalendarProvider.apk 日历程序支持服务(可删) *Camera.apk 自带相机(绝不能删除) *CertInstaller.apk 证书服务(绝不能删除) Contacts.apk 通讯录/联系人(用第三方通讯录的可删)*ContactsProvider.apk 通讯录/联系人数据存储服务(绝不能删除)*DefaultContainerService.apk 默认通讯录服务(绝不能删除) DeskClock.apk 自带闹钟(用第三方闹钟的可删) *DownloadProvider.apk 下载管理器(绝不能删除) *DrmProvider.apk DRM受保护数据存储服务(绝不能删除)DSPManager.apk DSP音频管理(可删) Email.apk Email(不用自带Email接受邮件的可删)FileManager.apk 简易文件管理器(可删,可用ES文件管理器替代) Gallery3D.apk 3D图片浏览器(可删) GenieWidget.apk 天气与新闻(可删) Gmail.apk Gmail(可删)GoogleBackupTransport.apk ***(未知程序,可删)GoogleCalendarSyncAdapter.apk 存储日历信息(可删)GoogleContactsSyncAdapter.apk 存储联系人信息(可删) GoogleFeedback.apk ***(据说删除后开机会提示GoogleFeedback.apk,根据自身情况决定是否删除) GooglePartnerSetup.apk Google助手(可删)

RK系统启动流程

RK29机型之Android系统启动流程 分类:瑞芯微RK 2012-02-12 14:50 4439人阅读评论(0) 收藏举报/******************************************************************************************** * author:conowen@大钟 * E-mail:conowen@https://www.doczj.com/doc/e19833302.html, * https://www.doczj.com/doc/e19833302.html,/conowen * 注:本文为原创,仅作为学习交流使用,转载请标明作者及出处。 ********************************************************************************************/ 第一步:系统引导bootloader,即RK29xxLoaderXXX.bin文件 加电后,CPU将先执行 bootloader程序,然后bootloader首先会读寄存器地址base + APP_DATA1的内容,根据这个地址的值决定是否进入recovery模式或者其它模式。bootloader还会读取MISC分区第一块的内容,决定进入recovery模式还是升级基带Baseband Processor(BP)或做其它事情 而上述寄存器与分区的值是有按键触发或者软件触发的。 a) 开机按reset+返回键,系统进入recovery模式,加载recovery.img,recovery.img 包含内核,基本的文件系统,用于工程模式的烧写 b) 开机按Power,正常启动系统,加载boot.img,boot.img包含内核,基本文件系统,用于正常启动机器(以下只分析正常启动的情况) 第二步:启动内核kernel 1) 源码:kernel/* 2) 说明:kernel由bootloader加载 第三步:文件系统(rootfs)及应用初始化(init) 1) 源码:system/core/init/* 2) 配置文件:system/rootdir/init.rc, 3) 说明:init是一个由内核启动的用户级进程,它按照init.rc中的设置执行:启动服务(这里的服务指linux底层服务,如adbd提供adb支持,vold提供SD卡挂载等),执行 命令和按其中的配置语句执行相应功能 第四步:重要的后台程序zygote 1) 源码:frameworks/base/cmds/app_main.cpp等 2) 说明:zygote是一个在init.rc中被指定启动的服务,该服务对应的命令是 /system/bin/app_process a) 建立Java Runtime,建立虚拟机

BOOTCHART ANDROID文档(开机慢)

BootChart在Android中的应用 1简介 Bootchart是一个能对GNU/Linux boot过程进行性能分析并把结果直观化的工具。它在boot过程中搜集资源利用情况及进程信息然后以PNG,SVG或EPS格式来显示结果。BootChart包含数据收集工具和图像产生工具,数据收集工具在原始的BootChart中是独立的shell程序,但在Android中,数据收集工具被集成到了init程序中。 2BootChart使用步骤概述 ?在主机上安装BootChart ?建立有BootChart支持的init文件 ?安装init到系统镜像 ?使能启动时的BootChart功能 ?收集系统产生的数据 ?根据产生的数据生成图表 ?结果分析 以下部分将对这些步骤进行详细描述(环境:Ubuntu9.04,Android1.6)。 3详细说明 ?在主机上安装BootChart $sudo apt-get install bootchart 注:由于BootChart是用Java语言实现,所以要求其所运行的主机安装Java包。 ?创建支持BootChart功能的‘init’文件 Andoid系统中运行的第一个程序是'init',其所在的目录为Andoid文件系统的根目录下(即/)。'init'是一个由内核启动的用户级进程,主要是对系统进行初始化和根据init.rc与init.xxx.rc文件建立几个基本的服务。 创建'init'时对BootChart的数据收集功能是可选的,默认的'init'是不支持BootChart 的数据收集功能的。要想在Andoid中应用BootChart,必须创建支持BootChart数据收集功能的'init'。 $cd~/myandroid $export INIT_BOOTCHART=true #vim system/core/init/Android.mk 20ifeq($(strip$(INIT_BOOTCHART)),true) 21LOCAL_SRC_FILES+=bootchart.c

Android SERVICE后台服务进程的自启动和保持

Android SERVICE后台服务进程的自启动和保持 Service组件在android开发中经常遇到,其经常作为后台服务,需要始终保持运行,负责处理一些必要(见不得人)的任务。而一些安全软件,如360等,会有结束 进程的功能,如果不做Service的保持,就会被其杀掉。 在早些时候,我们可以通过在 1. service中重写onStartCommand方法,这个方法有三个返回值, START_STICKY 是service被kill掉后自动 public int onStartCommand(Intent intent, int flags, int startId) { return START_STICKY; } 2. 配置android:persistent="true" 3. setForeground(true); 4. android:process=”com.xxx.xxxservice”配置到单独的进程中 以上的方法要么只是提升service优先级或者存活率, 并不能解决被安全软件强行 杀死的问题。要么像第四种单独的进程运行service在360老的版本是可以的,但是在360的比较新的版本中仍然会被杀死. 如何保持Service的运行状态是现在要说明的,核心就是利用ANDROID的系统广播,触发自己的程序检查Service的运行状态,如果被杀掉,就再起来。 常用的有开机广播,解锁屏幕的广播,电量变化等等,其中解屏的广播算比较频 繁的了,但是也并不能保证一定的频率,尤其是在特定的时间里(比如用户睡觉的时候,用户并不进行解锁操作).而我们仍要做一些操作的时候,就没有办法了。 因此,我采用了一种别的方案. 另外再加上两个类似一守护进程的Service,分别检查Service的运行状态,注册响应的广播,对其进行守护,一旦发现没有运行就将其 启动. 我利用的系统广播是:Intent.ACTION_TIME_TICK。这个广播每分钟发送一次, 我们可以每分钟检查一次Service的运行状态,如果已经被结束了,就重新启动Service。它的优点就是间隔时间短而且非常稳定, 而其他的广播并不能保证这一点,当然,在具体的应用中还是要根据需求使用, 结合其他广播来保证自己的service一定会 被重启。毕竟现在安全软件是越来越厉害了,更新得也是非常频繁. 有时间还是要看下还有没有其他的方法,综合几种来使用.

相关主题
文本预览
相关文档 最新文档