안 드 로 이 드 시스템 에서 응용 프로그램 앞 배경 전환 의 실현 요점 을 깊이 분석 하 다.
하나의 Activity 가 다른 Activity 를 시작 할 수 있다 는 것 을 잘 알 고 있 습 니 다.이 Activity 가 다른 프로그램 에 정의 되 어 있 더 라 도 예 를 들 어 사용자 에 게 지도 정 보 를 보 여 주 려 면 현재 Activity 가 이 일 을 할 수 있 습 니 다.그러면 현재 당신 의 Activity 가 해 야 할 일 은 요청 정 보 를 Intent 대상 에 넣 는 것 입 니 다.또한 이 Intent 대상 을 startActivity()에 전달 하면 지도 가 표 시 됩 니 다.그러나 사용자 가 Back 키 를 누 르 면 Activity 가 다시 화면 에 나타 납 니 다.
사용자 에 게 지 도 를 표시 하 는 Activity 와 당신 의 Activity 는 한 프로그램 에 있 는 것 같 습 니 다.다른 프로그램 에 정의 되 어 있 고 프로 세 스 에서 실행 되 고 있 지만.Android 는 사용자 의 체험 을 유지 하기 위해 Activity 와 빌 린 Activity 를 Task 에 넣 습 니 다.그러면 Task 는 스 택 형식 으로 서로 연 결 된 Activity 를 구성 합 니 다.스 택 의 아래쪽 에 있 는 Activity 는 바로 이 Task 를 개척 하 는 것 입 니 다.보통 사용자 가 응용 프로그램 실행 기 에서 선택 한 Activity 입 니 다.스 택 상단 의 Activity 는 현재 실행 중인 Activity-사용자 가 상호작용 하고 있 는 Activity 입 니 다.
하나의 Activity 가 다른 Activity 를 시작 할 때 새로 시작 한 Activity 가 스 택 에 눌 려 실행 중인 Activity 가 됩 니 다.오래된 Activity 는 여전히 스 택 에 있 습 니 다.사용자 가 BACK 키 를 눌 렀 을 때 실행 중인 Activity 팝 업 창 고 는 오래된 Activity 가 실행 중인 Activity 로 복 구 됩 니 다.스 택 에 대상 이 포함 되 어 있 기 때문에 하나의 작업 에서 같은 Activity 하위 클래스 의 여러 대상 을 열 었 다 면,예 를 들 어 여러 개의 지도 브 라 우 저―스 택 은 모든 인 스 턴 스 에 하나의 단독 입 구 를 가지 고 있 습 니 다.스 택 에 있 는 Activity 는 정렬 되 지 않 고 팝 업 만 됩 니 다.Task 는 Activity 인 스 턴 스 로 구 성 된 스 택 입 니 다.manifest 파일 의 특정한 종류 나 요소 가 아니 기 때문에 하나의 Task 속성 을 설정 할 수 없습니다.Activity 를 상관 하지 않 고 하나의 Task 의 모든 속성 값 은 아래쪽 Activity 에 설정 되 어 있 습 니 다.이것 은 Affinity 에 사용 해 야 합 니 다.Affinity 에 대해 서 는 더 이상 자세히 설명 하지 않 습 니 다.문 서 를 조회 할 수 있 습 니 다.
하나의 Task 에 있 는 모든 Activity 가 하나의 전체 로 작 동 합 니 다.전체 Task(전체 Activity 스 택)는 프론트 데스크 로 밀 리 거나 백 스테이지 로 밀 릴 수 있 습 니 다.실행 중인 Task 에 네 개의 Activity 가 있다 고 가정 합 니 다.실행 중인 Activity 아래 에 세 개의 Activity 가 있 습 니 다.이때 사용 자 는 HOME 키 를 누 르 고 프로그램 실행 기 를 누 른 다음 에 새로운 프로그램 을 실행 합 니 다.(실제로 새로운 Task 가 실행 되 었 습 니 다)현재 Task 는 배경 으로 물 러 갑 니 다.새로 시작 한 프로그램의 root Activity 가 이때 표 시 됩 니 다.한 동안 사용 자 는 다시 응용 프로그램 으로 돌아 가 이전의 응용 프로그램(이전의 그 Task)을 다시 선택 했다.그러면 이전의 그 Task 는 이때 다시 프론트 데스크 로 돌 아 왔 다.사용자 가 BACK 키 를 눌 렀 을 때 화면 은 방금 떠 난 그 응용 프로그램의 Activity 를 표시 하 는 것 이 아니 라 프론트 데스크 로 돌아 간 Task 의 스 택 꼭대기 Activity 를 제외 했다.이 Task 의 다음 Activity 를 표시 합 니 다.상술 한 것 이 바로 Activity 와 Task 의 일반적인 행위 이지 만 이 행 위 는 거의 모든 면 에서 수정 할 수 있다.Activity 와 Task 의 관계,그리고 Task 에서 Activity 의 행 위 는 이 Activity 를 시작 하 는 Intent 대상 의 표지 와 manifest 파일 에 있 는 Activity 의
이상 은 Activity 와 Task 에 대한 설명 입 니 다.
안 드 로 이 드 프로젝트 를 개발 할 때 사용 자 는 프로그램 전환 을 피 할 수 없 으 며,전환 과정 에서 프로그램 은 백 엔 드 로 들 어가 실행 되 며,필요 할 때 작업 관리자 나 프로그램 을 다시 클릭 하거나 정보 알림 표시 줄 에 있 는 아이콘 을 클릭 하여 원래 의 인터페이스 로 돌아 갑 니 다.이러한 효 과 는 텐 센트 QQ 와 유사 합 니 다.QQ 를 열 면 메 인 화면 을 표시 하고,다른 프로그램 을 사용 할 때 QQ 는 아이콘 으로 정보 알림 표시 줄 에 표시 하 며,QQ 를 사용 할 때 정보 알림 표시 줄 에 있 는 아이콘 을 클릭 하면 QQ 메 인 화면 을 표시 합 니 다.
먼저 본 예시 의 실현 효과 도 를 보십시오.
위의 그림 두 번 째 그림 에서 우리 가 클릭 하면 원래 의 Activity 로 돌아 갑 니 다.
우리 의 프로그램 이 배경 에 들 어가 서 작 동 할 때 우리 의 시 뮬 레이 터 상단 에 아이콘 형식 으로 나타 날 것 입 니 다.다음 그림:
이러한 효과 에 대해 일반적인 방법 은 Activity 의 onStop()방법 에서 해당 하 는 코드 를 작성 하 는 것 입 니 다.Activity 가 배경 에 들 어 갈 때 onStop()방법 을 호출 하기 때문에 저 희 는 onStop()방법 에서 Notification 형식 으로 프로그램 아이콘 과 정 보 를 표시 할 수 있 습 니 다.그 중에서 대 호 는 다음 과 같 습 니 다.
@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
Log.v("BACKGROUND", " ");
showNotification();
}
이상 의 쇼 Notification()방법 은 Notification 입 니 다.그리고 정보 알림 표시 줄 의 Notification 을 클릭 한 후 원래 의 Activity 로 돌아 갑 니 다.
물론 HOME 키 를 포착 할 수 있 습 니 다.사용자 가 HOME 키 를 눌 렀 을 때 Notification 을 표시 합 니 다.다음은 코드 예제 입 니 다.
// HOME
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
// HOME
if(keyCode == KeyEvent.KEYCODE_HOME){
// Notification
notification = new NotificationExtend(this);
notification.showNotification();
moveTaskToBack(true);
return true;
}
return super.onKeyDown(keyCode, event);
}
여기 NotificationExtend 는 Notification 을 표시 하 는 패키지 입 니 다.클래스 의 코드 는 다음 과 같 습 니 다.
package com.test.background;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.graphics.Color;
/**
* Notification
* @Description: Notification
* @File: NotificationExtend.java
* @Package com.test.background
*/
public class NotificationExtend {
private Activity context;
public NotificationExtend(Activity context) {
// TODO Auto-generated constructor stub
this.context = context;
}
// Notification
public void showNotification() {
// NotificationManager
NotificationManager notificationManager = (
NotificationManager)context.getSystemService(
android.content.Context.NOTIFICATION_SERVICE);
// Notification
Notification notification = new Notification(
R.drawable.icon," ",
System.currentTimeMillis());
// "Ongoing" " "
notification.flags |= Notification.FLAG_ONGOING_EVENT;
// " " , 。
notification.flags |= Notification.FLAG_AUTO_CANCEL
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
notification.defaults = Notification.DEFAULT_LIGHTS;
notification.ledARGB = Color.BLUE;
notification.ledOnMS = 5000;
//
CharSequence contentTitle = " "; //
CharSequence contentText = " , ……"; //
Intent notificationIntent = new Intent(context,context.getClass());
notificationIntent.setAction(Intent.ACTION_MAIN);
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
PendingIntent contentIntent = PendingIntent.getActivity(
context, 0, notificationIntent,PendingIntent.FLAG_UPDATE_CURRENT);
notification.setLatestEventInfo(
context, contentTitle, contentText, contentIntent);
// Notification NotificationManager
notificationManager.notify(0, notification);
}
//
public void cancelNotification(){
NotificationManager notificationManager = (
NotificationManager) context.getSystemService(
android.content.Context.NOTIFICATION_SERVICE);
notificationManager.cancel(0);
}
}
설정 파일 에 모든 Activity 를 단일 작업 으로 실행 하도록 설정 해 야 합 니 다.그렇지 않 으 면 원래 Activity 로 돌아 갈 때마다 Activity 가 새로 추 가 됩 니 다.원래 Activity 로 돌아 가지 않 습 니 다.FLAG 사용 중ACTIVITY_NEW_TASK 가 표 지 를 제어 할 때 도 기 존 액 티 비 티 로 되 돌아 가지 않 는 현상 이 나타난다.이 표지 가 Activity 로 하여 금 새로운 Task 를 시작 하 게 한 다음 에 사용자 가 HOME 키 를 눌 러 이 Activity 를 떠 나 면 사용자 가 BACK 키 를 눌 렀 을 때 원래 Activity 로 돌아 갈 수 없습니다.일부 응용 프로그램(예 를 들 어 Notification)은 항상 새로운 Task 에서 Activity 를 열 고 자신의 Task 에서 열지 않 기 때문에 항상 FLAG 를 포함 합 니 다.ACTIVITY_NEW_TASK 의 인 텐트 는 startActivity()에 전달 된다.따라서 이 제어 표지 로 다른 것 에 의 해 호출 될 수 있 는 Activity 가 있다 면 프로그램 이 독립 적 으로 원래 Activity 로 돌아 가 는 방법 을 주의 하 십시오.코드 는 다음 과 같 습 니 다:
<activity android:name="ShowMessageActivity"
android:launchMode="singleTask"></activity>
Android 응용 전 배경 전환 판단안 드 로 이 드 에 서 는 응용 프로그램 앞 배경 에서 전환 하 는 리 셋 이나 방송 을 제공 하지 않 았 습 니 다.이 기능 은 우리 만 처리 할 수 있 습 니 다.이전에 이 문제 에 부 딪 힌 처리 방식 은 BaseActivity 를 실현 한 다음 에 다른 모든 Activity 를 계승 한 다음 에 생명주기 함수 에서 해당 하 는 검 측 을 하 는 것 이다.구체 적 인 검 측 방법 은 다음 과 같다.
Activity 의 onStart 와 onStop 방법 에서 계산 합 니 다.계수 변 수 는 count 이 고 onStart 에서 변 수 를 1,onStop 에서 1 을 빼 고 두 개의 Activity 가 있다 고 가정 합 니 다.각각 A 와 B 입 니 다.
상황 1.먼저 A 를 시작 하고 A 를 다시 시작 합 니 다.B:시작 A,count=1,A 가 B 를 시작 합 니 다.생명주기 의 순 서 는 B.onStart->A.onStop 이 고 count 의 수 는 1 입 니 다.
상황 2.먼저 A 를 시작 한 다음 홈 키 를 누 르 면 데스크 톱 으로 돌아 갑 니 다.A,count=1 을 시작 하고 홈 키 를 누 르 면 데스크 톱 으로 돌아 갑 니 다.A.onStop,count 의 계수 변 위 0 을 실행 합 니 다.
위의 두 가지 상황 을 통 해 알 수 있 듯 이 count 수 를 0 으로 계산 함으로써 응용 이 프론트 에서 백 스테이지 로 잘 렸 다 는 것 을 판단 할 수 있다.백 스테이지 에서 프런트 로 자 르 는 것 도 비슷 한 이치 다.구체 적 으로 뒤에 있 는 코드 를 보 세 요.
그러나 프로젝트 에서 모든 Activity 가 같은 BaseActivity 에서 계승 되 는 것 이 아니라면 이 기능 을 실현 할 수 없다.다행히도 안 드 로 이 드 는 API 14 이후 애플 리 케 이 션 류 에서 라 이 프 사이클 리 셋 을 사용 하 는 등록 방법 을 제공 하여 응용 수명 주 기 를 집중 적 으로 관리 합 니 다.이 인 터 페 이 스 는 registerActivity LifecycleCallbacks 라 고 하 는데 이 를 통 해 자신의 Activity Life CycleCallback 을 등록 할 수 있 습 니 다.모든 Activity 의 생명주기 가 이곳 으로 되 돌아 오 는 대응 방법.사실 이 등록 방법의 본질은 우리 가 BaseActivity 를 실현 하 는 것 과 같 고 생명주기 관 리 를 Activity 자체 의 실현 으로 옮 겼 을 뿐이다.
구체 적 인 사용 방법 은 다음 과 같다.
public class MyApplication extends Application{
public int count = 0;
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityStopped(Activity activity) {
Log.v("viclee", activity + "onActivityStopped");
count--;
if (count == 0) {
Log.v("viclee", ">>>>>>>>>>>>>>>>>>> lifecycle");
}
}
@Override
public void onActivityStarted(Activity activity) {
Log.v("viclee", activity + "onActivityStarted");
if (count == 0) {
Log.v("viclee", ">>>>>>>>>>>>>>>>>>> lifecycle");
}
count++;
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
Log.v("viclee", activity + "onActivitySaveInstanceState");
}
@Override
public void onActivityResumed(Activity activity) {
Log.v("viclee", activity + "onActivityResumed");
}
@Override
public void onActivityPaused(Activity activity) {
Log.v("viclee", activity + "onActivityPaused");
}
@Override
public void onActivityDestroyed(Activity activity) {
Log.v("viclee", activity + "onActivityDestroyed");
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Log.v("viclee", activity + "onActivityCreated");
}
});
}
}
그 밖 에 이 기능 을 실현 할 수 있 는 다른 방법 이 있 습 니까?응용 프로그램 이 배경 으로 자 를 때 프론트 데스크 톱 에서 실행 되 는 프로 세 스 는 우리 의 app 에서 데스크 톱 app 으로 바 뀌 었 습 니 다.이 점 에 따라 우 리 는 응용 프로그램 전 배경 전환 을 감지 하 는 기능 을 실현 할 수 있 습 니 다.Activity 의 onStop 라 이 프 사이클 에서 검색 코드 를 실행 합 니 다.현재 프론트 데스크 에서 실행 중인 프로 세 스 가 우리 자신의 프로 세 스 가 아 닌 것 을 발견 하면 응용 프로그램 이 배경 으로 잘 렸 다 는 것 을 설명 합 니 다.
onPause 가 아 닌 왜 onStop 에서 검 측 했 는 지 생각해 보 세 요.이것 은 A 가 B 를 시작 할 때 생명주기 의 실행 순 서 는 다음 과 같 기 때문이다.A.onPause->B.onCreate->B.onStart->B.onResume->A.onStop.즉,A 의 onPause 방법 에서 B 의 생명주기 가 아직 실행 되 지 않 았 고 프로 세 스 가 프론트 에 들 어가 지 않 았 기 때문에 당연히 검출 되 지 않 았 다.우 리 는 코드 를 onPause 생명주기 로 옮 겼 는데,확실히 효과 가 없다 는 것 을 발견 했다.
구체 적 인 실현 코드 는 다음 과 같다.
//
private boolean isCurrentRunningForeground = true;
@Override
protected void onStart() {
super.onStart();
if (!isCurrentRunningForeground) {
Log.d(TAG, ">>>>>>>>>>>>>>>>>>> activity process");
}
}
@Override
protected void onStop() {
super.onStop();
isCurrentRunningForeground = isRunningForeground();
if (!isCurrentRunningForeground) {
Log.d(TAG,">>>>>>>>>>>>>>>>>>> activity process");
}
}
public boolean isRunningForeground() {
ActivityManager activityManager = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcessInfos = activityManager.getRunningAppProcesses();
//
for (ActivityManager.RunningAppProcessInfo appProcessInfo : appProcessInfos) {
if (appProcessInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
if (appProcessInfo.processName.equals(this.getApplicationInfo().processName)) {
Log.d(TAG,"EntryActivity isRunningForeGround");
return true;
}
}
}
Log.d(TAG, "EntryActivity isRunningBackGround");
return false;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 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에 따라 라이센스가 부여됩니다.