Android 더 블 프로 세 스 데 몬 구현 코드
최근 프로젝트 에 고 덕 을 사용 하 는 포 지 셔 닝 SDK 가 있 는데,일정 시간 마다 사용자 의 지리 적 위 치 를 가 져 오 는 기능 이 있 으 며,배경 에 서 비 스 를 열 어 고 덕 지도의 위치 변 화 를 감청 하 는 방안 을 채택 했다.
이 기능 은 사용자 의 휴대 전화 화면 이 밝 아 졌 을 때 완벽 하 게 실현 되 었 으 나 화면 이 꺼 졌 을 때 위치 정 보 를 얻 을 수 없 었 다.원인 을 조사 한 결과 사용자 의 휴대 전화 화면 이 꺼 진 후에 백 스테이지 의 Service 가 시스템 에 의 해 제거 되 었 기 때문에 기능 이 작 동 하지 않 았 다.즉,프로 세 스 가 죽 었 다 는 것 이다.
프로 세 스 를 죽 이 는 것 은 한편 으로 는 핸드폰 메모리 가 부족 하기 때 문 입 니 다.다른 한편 으로 는 구 글 이 사용자 의 측면 에서 볼 때 백 스테이지 에 상주 하 는 프로그램 을 일정한 알고리즘 을 통 해 관리 하고 시스템 자원 을 과도 하 게 소모 하 는 건달 소프트웨어 를 제거 하여 핸드폰 의 성능 과 지속 을 보장 합 니 다.그러나 어떤 소프트웨어 는 포 지 셔 닝 과 같은 백 스테이지 운행 을 유지 해 야 시스템 에 의 해 죽 는 것 을 피 할 수 있 습 니까?사실 피 살 프로 세 스 를 피 하 는 것 은 어렵 습 니 다.위 챗,QQ,알 리 페 이 같은 시스템 업 체 가 인정 하 는 소프트웨어 가 공식 적 으로 화이트 리스트 에 가입 되 지 않 는 한 피 살 프로 세 스 를 피 할 수 있 습 니 다.그 다른 작은 소프트웨어 는 어떻게 합 니까?우 리 는 다른 길 을 개척 할 수 있 습 니 다.피 살 프로 세 스 를 피 할 수 없습니다.그러면 우리 의 소프트웨어 는 피 살 프로 세 스 후에 자동 으로 재 부팅 할 수 있 습 니 다.
프로 세 스 가 살 해 된 후 끌 어 올 리 는 방법 을 소개 합 니 다.
두 프로 세 스 데 몬
두 프로 세 스 를 지 키 는 사상 은 두 프로 세 스 가 공동으로 실행 되 는 것 입 니 다.만약 에 한 프로 세 스 가 죽 으 면 다른 프로 세 스 는 살 해 된 프로 세 스 를 다시 끌 어 올 리 고 서로 보호 하 며 일정한 의미 에서 프로 세 스 의 끊 임 없 는 운행 을 유지 합 니 다.
두 프로 세 스 가 지 키 는 두 프로 세 스 입 니 다.한 프로 세 스 는 우리 가 필요 로 하 는 배경 작업 에 사용 되 고 로 컬 프로 세 스 라 고 부 릅 니 다.다른 프로 세 스 는 로 컬 프로 세 스 의 상 태 를 감청 하 는 것 만 담당 합 니 다.로 컬 프로 세 스 가 죽 었 을 때 끌 어 올 리 려 고 합 니 다.이 프로 세 스 를 원 격 프로 세 스 라 고 부 릅 니 다.
Android 에 서 는 두 프로 세 스 간 에 직접 상호작용 을 할 수 없 기 때문에 AIDL(Android interface definition Language)을 사용 하여 두 프로 세 스 간 의 상호작용 을 해 야 합 니 다.
코드 구현
먼저 demo 코드 구 조 를 살 펴 보 겠 습 니 다.구조 가 간단 합 니 다.저 는 Activity 를 인터페이스 로 만 들 었 고 두 개의 Service 를 만 들 었 습 니 다.하 나 는 배경 에서 작 동 하 는 로 컬 Service 이 고 다른 하 나 는 데 몬 의 원 격 Service 이 며 또 하 나 는 AIDL 파일 을 프로 세 스 간 의 상호작용 으로 사용 합 니 다.
프로젝트 구조
Activity 의 정 의 는 매우 간단 합 니 다.몇 개의 버튼 으로 Service 의 상 태 를 제어 합 니 다.저 는 세 개의 단 추 를 정 의 했 습 니 다.하 나 는 배경 서 비 스 를 시작 하 는 것 이 고 다른 두 개 는 로 컬 Service 와 원 격 서 비 스 를 닫 는 것 입 니 다.
/**
* @author chaochaowu
*/
public class GuardActivity extends AppCompatActivity {
@BindView(R.id.button)
Button button;
@BindView(R.id.button2)
Button button2;
@BindView(R.id.button3)
Button button3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.activity_guard);
ButterKnife.bind(this);
}
@OnClick({R.id.button, R.id.button2, R.id.button3})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.button:
startService(new Intent(this, LocalService.class));
break;
case R.id.button2:
stopService(new Intent(this, LocalService.class));
break;
case R.id.button3:
stopService(new Intent(this, RemoteService.class));
break;
default:
break;
}
}
}
화면 을 볼 수 있 습 니 다.메 인 인터페이스
AIDL 파일 은 업무 상 필요 에 따라 인 터 페 이 스 를 추가 할 수 있 습 니 다.
/**
* @author chaochaowu
*/
interface IMyAidlInterface {
String getServiceName();
}
중요 한 것 은 두 서비스 에 있다.Service 를 정의 할 때 AndroidManifest 에서 원 격 Service 의 process 속성 을 설명 하고 로 컬 Service 와 원 격 Service 두 가지 가 서로 다른 프로 세 스에 서 달 릴 수 있 도록 해 야 합 니 다.같은 프로 세 스에 서 달 려 가면 이 프로 세 스 가 죽 으 면 아무것도 없습니다.더 블 데 몬 이라는 말 이 없습니다.
<service
android:name=".guard.LocalService"
android:enabled="true"
android:exported="true" />
<service
android:name=".guard.RemoteService"
android:enabled="true"
android:exported="true"
android:process=":RemoteProcess"/>
먼저 LocalService 의 코드 를 살 펴 보고 onStartCommand 방법 과 ServiceConnection 에서 다시 쓰 는 방법 에 중점 을 둡 니 다.onStartCommand 방법 은 Service 가 시 작 된 후에 호출 되 었 습 니 다.LocalService 가 시 작 된 후에 저 희 는 RemoteService 를 시 작 했 고 LocalService 와 RemoteService 두 가 지 를 연결 시 켰 습 니 다.(원 격 서 비 스 는 사용자 에 게 보이 지 않 기 때문에 저희 가 실제 작업 하 는 프로 세 스에 비해 독립 적 이 고 그 역할 은 수호 스 레 드 일 뿐 입 니 다.그래서 RemoteService 는 LocalService 와 만 관련 이 있 고 LocalService 에서 만 시작 할 수 있 을 것 입 니 다).시작 하고 연결 한 후에 저 희 는 ServiceConnection 의 방법 을 다시 써 야 합 니 다.이들 의 연결 관 계 를 감청 해 야 합 니 다.관건 은 이들 의 연결 관계 가 끊 겼 을 때의 감청 입 니 다.
그 중의 한 프로 세 스 가 죽 었 을 때 이들 의 바 인 딩 관 계 는 끊 어 집 니 다.트리거 방법 인 onServiceDisconnected 를 실행 합 니 다.따라서 우 리 는 끊 었 을 때 프로 세 스 가 끌 어 올 리 는 작업 을 하고 onServiceDisconnected 방법 을 다시 쓰 며 다른 서 비 스 를 다시 시작 하고 두 가 지 를 다시 연결 해 야 합 니 다.
/**
* @author chaochaowu
*/
public class LocalService extends Service {
private MyBinder mBinder;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IMyAidlInterface iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
try {
Log.i("LocalService", "connected with " + iMyAidlInterface.getServiceName());
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(LocalService.this," , RemoteService",Toast.LENGTH_LONG).show();
startService(new Intent(LocalService.this,RemoteService.class));
bindService(new Intent(LocalService.this,RemoteService.class),connection, Context.BIND_IMPORTANT);
}
};
public LocalService() {
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this,"LocalService ",Toast.LENGTH_LONG).show();
startService(new Intent(LocalService.this,RemoteService.class));
bindService(new Intent(this,RemoteService.class),connection, Context.BIND_IMPORTANT);
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
mBinder = new MyBinder();
return mBinder;
}
private class MyBinder extends IMyAidlInterface.Stub{
@Override
public String getServiceName() throws RemoteException {
return LocalService.class.getName();
}
}
}
또 다른 RemoteService 에서 도 마찬가지 로 LocalService 와 링크 를 끊 었 을 때 바 인 딩 이 끊 어 지 는 것 을 감청 한 것 은 RemoteService 가 살아 있 고 LocalService 가 살 해 된 프로 세 스 라 는 것 을 의미 하기 때문에 LocalService 를 끌 어 올 리 고 다시 연결 해 야 합 니 다.방법 은 onServiceDisconnected 에 적 혀 있 습 니 다.
/**
* @author chaochaowu
*/
public class RemoteService extends Service {
private MyBinder mBinder;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IMyAidlInterface iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
try {
Log.i("RemoteService", "connected with " + iMyAidlInterface.getServiceName());
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(RemoteService.this," , LocalService",Toast.LENGTH_LONG).show();
startService(new Intent(RemoteService.this,LocalService.class));
bindService(new Intent(RemoteService.this,LocalService.class),connection, Context.BIND_IMPORTANT);
}
};
public RemoteService() {
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this,"RemoteService ",Toast.LENGTH_LONG).show();
bindService(new Intent(this,LocalService.class),connection,Context.BIND_IMPORTANT);
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
mBinder = new MyBinder();
return mBinder;
}
private class MyBinder extends IMyAidlInterface.Stub{
@Override
public String getServiceName() throws RemoteException {
return RemoteService.class.getName();
}
}
}
실행 효과Activity 를 시작 하려 면 LocalService 를 클릭 하여 로 컬 서 비 스 를 시작 합 니 다.알림 에서 알 수 있 듯 이 LocalService 가 시작 되면 RemotService 데 몬 스 레 드 도 시 작 됩 니 다.이때,둘 은 이미 한데 묶 였 다.
서비스 시작
LocalService 를 닫 으 면 로 컬 프로 세 스 가 죽 임 을 모 의 합 니 다.Toast 알림 링크 가 끊 기 고 LocalService 를 다시 시작 하려 고 합 니 다.두 번 째 Toast 알림 LocalService 가 다시 시작 되 었 습 니 다.
로 컬 서비스 닫 기
RemoteService 닫 기 를 누 르 면 원 격 프로 세 스 가 죽 임 을 모 의 합 니 다.Toast 알림 링크 가 끊 기 고 RemoteService 를 다시 시작 하려 고 합 니 다.두 번 째 Toast 알림 RemoteService 가 다시 시작 되 었 습 니 다.
원 격 서비스 닫 기
우리 가 프로 세 스 를 어떻게 죽 이 든 프로 세 스 가 다시 끌 어 올 리 는 것 을 발견 할 수 있 습 니 다.이것 은 Service 가 활성화 되 고 두 프로 세 스 가 서로 지 키 는 목적 을 달성 할 수 있 습 니 다.
총결산
개발 과정 에서 피 할 수 없 는 번 거 로 움 이 있 지만 방법 은 어려움 보다 많 으 니 인내심 을 가지 고 연구 하면 된다.프로 세 스 의 보존 에 관 해 서 는 사실 방법 이 없다.우 리 는 프로 세 스 를 백 스테이지 에 상주 시 키 는 것 을 최대한 피해 야 한다.만약 정말 필요 하 다 면 백 스테이지 작업 을 마 친 후에 도 제때에 그들 을 소각 해 야 한다.그렇지 않 으 면 백 스테이지 프로 세 스 가 이유 없 이 시스템 자원 을 소모 하고 사용자 가 모 르 면 우리 의 소프트웨어 도 깡패 소프트웨어 가 된다.개발 자 는 양심 이 있어 야 지,응?
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.