日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

android 8.0可以实现后台包活么,Android 8.0 应用保活实践 · Jaqen Ng

發布時間:2023/11/27 生活经验 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android 8.0可以实现后台包活么,Android 8.0 应用保活实践 · Jaqen Ng 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

8種機械鍵盤軸體對比

本人程序員,要買一個寫代碼的鍵盤,請問紅軸和茶軸怎么選?

雖然我也覺得強行保活應用挺不厚道的,但是沒辦法,為了完成需求。

一開始嘗試的方案是 Android 5.0 后系統提供的 JobScheduler,能夠預先設置條件,達到條件時自動啟動 JobService,在 Android 8.0 以下都能很愉快的使用。但是在華為的 Android 8.0 上,當應用被殺后,JobService 就不能被系統調用了。

于是采取了雙進程服務綁定方式,實現了應用保活功能。

直接看原理圖:

原理就是利用 Binder 的訃告機制,如果 Service Binder 實體的進程被殺,系統會向 Client 發送訃告,這個時機就是保活的空子了。所以可以通過兩個進程啟動兩個 Binder 服務,互為 C/S,一旦一個進程掛掉,另一個進程就會收到 Binder 訃告,這時可以拉起另一個進程。

那么圖中兩個進程中的 TransferActivity 是干什么用的 ,這個在后面再說。

這里我寫了兩個應用,一個是 AIDLServer,相當于服務端;一個是 AIDLClient,相當于客戶端。而兩個進程之間的通信采用 AIDL 方式。1

2

3

4

5

6

7

8

9

10

11

12package com.wuzy.aidlserver;

// Declare any non-default types here with import statements

interface{

void bindSuccess();

void unbind();

}

注意兩個應用的 AIDL 文件必須一致,包括包名。

然后,編寫兩個 binder 實體服務 RemoteService 、LocalService,主要代碼如下:1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61public class RemoteService extends Service{

private static final String TAG = "RemoteService";

public void onCreate(){

super.onCreate();

Log.e(TAG, "onCreate: 創建 RemoteService");

bindLocalService();

}

public IBinder onBind(Intent intent){

return stub;

}

private IMyAidlInterface.Stub stub = new IMyAidlInterface.Stub() {

public void bindSuccess() throws RemoteException{

Log.e(TAG, "bindSuccess: LocalService 綁定 RemoteService 成功");

}

public void unbind() throws RemoteException{

Log.e(TAG, "unbind: 此處解除 RemoteService 與 LocalService 的綁定");

getApplicationContext().unbindService(connection);

}

};

/**

* 綁定 LocalService

*/

private void bindLocalService(){

Intent intent = new Intent();

intent.setComponent(new ComponentName("com.wuzy.aidlclient", "com.wuzy.aidlclient.LocalService"));

if (!getApplicationContext().bindService(intent, connection, Context.BIND_AUTO_CREATE)) {

Log.e(TAG, "bindLocalService: 綁定 LocalService 失敗");

stopSelf();

}

}

private ServiceConnection connection = new ServiceConnection() {

public void onServiceConnected(ComponentName name, IBinder service){

}

@Override

public void onServiceDisconnected(ComponentName name){

// bindRemoteService();

createTransferActivity();

}

};

private void createTransferActivity(){

Intent intent = new Intent(this, TransferActivity.class);

intent.setAction(TransferActivity.ACTION_FROM_SELF);

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

startActivity(intent);

}

}1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59public class LocalService extends Service{

private static final String TAG = "LocalService";

@Override

public void onCreate(){

super.onCreate();

Log.e(TAG, "onCreate: 創建 LocalService");

bindRemoteService();

}

@Override

public IBinder onBind(Intent intent){

Log.e(TAG, "onBind: 綁定 LocalService");

return stub;

}

private IMyAidlInterface.Stub stub = new IMyAidlInterface.Stub() {

@Override

public void bindSuccess() throws RemoteException{

Log.e(TAG, "bindSuccess: RemoteService 綁定 LocalService 成功");

}

@Override

public void unbind() throws RemoteException{

getApplicationContext().unbindService(connection);

}

};

private ServiceConnection connection = new ServiceConnection() {

@Override

public void onServiceConnected(ComponentName name, IBinder service){

}

@Override

public void onServiceDisconnected(ComponentName name){

// bindRemoteService();

createTransferActivity();

}

};

private void createTransferActivity(){

Intent intent = new Intent(this, TransferActivity.class);

intent.setAction(TransferActivity.ACTION_FROM_SELF);

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

startActivity(intent);

}

private void bindRemoteService(){

Intent intent = new Intent();

intent.setComponent(new ComponentName("com.wuzy.aidlserver", "com.wuzy.aidlserver.RemoteService"));

if (!getApplicationContext().bindService(intent, connection, Context.BIND_AUTO_CREATE)) {

Log.e(TAG, "bindRemoteService: 綁定 RemoteService 失敗");

stopSelf();

}

}

}

在 onCreate 的時候相互綁定,并在 onServiceDisconnected 收到訃告的時候,重新啟動服務綁定彼此即可。

但是我在系統是 8.0 的華為機器上是無效的,也就是當 LocalService 所在進程被殺后,RemoteService 無法啟動LocalService,反過來也是如此。

所以,這里只能采取 “曲線救國” 的方式。通過 TransferActivity 中轉下,先啟動守護進程的 TransferActivity,再從守護進程的 TransferActivity 中啟動保活進程的 TransferActivity,這是沒有問題的,再從保活進程的 TransferActivity 中啟動 LocalService,重新綁定服務即可,反過來也是一樣的。當然,TransferActivity 要用戶無感知,不然會很突兀,所以這里的 TransferActivity 都是 1 個像素,做完任務及時銷毀即可。

TransferActivity 的代碼就不貼了,具體可以去 GitHub 了解。

這種方式用來保活一般是沒有問題的,因為 Binder 訃告是系統中 Binder 框架自帶的,除非一次性殺了兩個進程,那就沒轍了。

最后,一般保活的目的是為了做某項任務,所以,任務完成后應該結束保活功能,不然老是占著內存確實挺不厚道的。

總結

以上是生活随笔為你收集整理的android 8.0可以实现后台包活么,Android 8.0 应用保活实践 · Jaqen Ng的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。