Development record of developer who study hard everyday.

레이블이 android workmanager인 게시물을 표시합니다. 모든 게시물 표시
레이블이 android workmanager인 게시물을 표시합니다. 모든 게시물 표시
, , ,

안드로이드 WorkManager 사용하기 (자바 JAVA)

 안드로이드 WorkManager 사용법 소개


회사 프로젝트를 진행하던 중 매우 난감한 상황에 봉착했다.

깃에서 가장 최신 소스를 clone 받아보니 targetSDK가 29였다.

마켓에 올리려면 targetSDK가 30은 되야하는데 어짜피 내년에도 내가 이 프로젝트를 건드려야하니까 32까지 올려보려고 했다. (매년 조금씩 수정할 것이 있는 프로젝트임)

tartgetSDK는 32까지 겨우겨우 올렸는데 여기에 쓰인 라이브러리 중에 android.evernote.job 이란 라이브러리가 있었다.

근데 이 라이브러리가 targetSDK 31부터는 deprecated 되었으니 workManager랑 alarmManager를 사용하라는 것이다!!

하.... 일이 늘어나버렸다.

내년에도 어짜피 내가 해야할 프로젝트라서 그냥 이번에 큰 맘 먹고 대폭 수정하기로 했다.

겸사겸사 전에 잠깐 공부해뒀던 WorkManager도 활용해보기로하고 말이다.

그럼 WorkManager 사용법에 대해 알아보자!

참, 기존의 프로젝트가 자바로 된 녀석이여서 자바 기준으로 설명하겠다;;

1. WorkManager dependency 추가

def work_version = "2.7.1"
implementation "androidx.work:work-runtime:$work_version"

앱수준 build.gradle에 위와 같이 workManager 라이브러리를 추가해준다.

되도록 2.7.0 이상의 버전을 추가하길 바란다.

너무 낮은 버전을 추가하면 

Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent. Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.

위와 같은 에러가 발생하는 경우가 있다.

2.  Worker 객체 만들기

public class DetectionWork extends Worker {    //1
public static final String TAG = DetectionWork.class.getSimpleName();
private static final int NOTIFICATION_ID = 1111;

public DetectionWork(
@NonNull Context context,
@NonNull WorkerParameters params) {
super(context, params);
}

@NonNull
@Override
public Result doWork() {    //2
Log.d(TAG, "DetectionWork doWork()");    //3
NotificationTool.show(getApplicationContext(), "이번 달 유방암 자가검진일인 핑크터치 데이입니다",    //3
null, "유방암 자가검진 시작", new HashMap<>(), NOTIFICATION_ID);    //3

return Result.success();    //4
}
}

1-> Worker 객체를 상속한다.

2-> doWork() 메소드를 override 해준다.

3-> workManager로 동작할 코드를 적어준다.

4-> 성공을 return 해준다.

3-> WorkRequest 객체 만들기

WorkRequest DetectionWorkRequest = new OneTimeWorkRequest.Builder(DetectionWork.class)    //1
.addTag(DetectionWork.
TAG)    //2
.setInitialDelay(getAlarmTime()
, TimeUnit.MILLISECONDS)    //3
.build();

WorkManager.getInstance(mApplication.getApplicationContext()).enqueue(DetectionWorkRequest);    //4

1-> 한 번만 실행할 거라서 OneTimeWorkRequest 객체를 만든다.

2-> 나중에 취소할 경우를 생각해서 Tag를 만들어준다.

3-> 특정 시간 뒤에 동작하기위해 setInitialDelay 메소드 사용

4-> WorManager 객체에 enqueue를 하면 Worker 객체가 실행된다!


내가 작성한 코드가 WorkManager의 가장 기본적인 형태라고 보면된다.

이외에도 다양한 기능들이 있는데 공식홈페이지를 참고하길 바란다.


✋여기서 잠깐!

내가 WorkManager를 사용하면서 매우 당황한 에러로그가 있었다.

WorkManager is not initialized properly.  You have explicitly disabled WorkManagerInitializer in your manifest, have not manually called WorkManager#initialize at this point, and your Application does not implement Configuration.Provider.

위와 같은 로그였는데, 아직도 왜 발생했는지 정확한 이유는 모르겠다..

아무리 문서를 찾아보고 스택오버플로우를 뒤져봐도 아직 모르겠다...

다만, addTag 기능을 사용하면서 기본 WorkManager의 초기화가 아니라 커스텀 초기화가 필요했던 것 같다.

아무튼, 위와 같은 로그가 발생했을 때 해결 방방법은 다음과 같다.

1. 워크매니저의 기본 초기화 제거

<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<!-- If you are using androidx.startup to initialize other components -->
<meta-data
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>

manifest.xml 파일에 <application> 태그 안에 위 코드를 넣어준다.

코드의 내용은 간단히 설명하면 WorkManager의 기본 초기화를 제거한다는 뜻이다.

2. 워크매니저의 커스텀 초기화

기본 초기화를 제거했으니 WorkManager를 커스텀 초기화를 해주어야한다.

public class MainApplication extends BaseApplication implements Configuration.Provider {

@Override
public void onCreate() {
super.onCreate();

addRegisterCallback();

ViewPump.init(ViewPump.builder()
.addInterceptor(new CalligraphyInterceptor(
new CalligraphyConfig.Builder()
.setDefaultFontPath("fonts/youth.ttf")
.build()))
.build());
}

@NonNull
@Override
public Configuration getWorkManagerConfiguration() {
return new Configuration.Builder()
.setMinimumLoggingLevel(Log.INFO)
.build();
}
}

Application을 상속하는 클래스(여기서는 MainApplication)에 가서 Configuration.Provider를 implements 해준다.

그리고 getWorkManagerConfiguration 메소드를 override해준다.

이렇게하면 WorkManager를 커스텀 초기화를 하게된다.

그리고 에러로그는 사라진다!




Share:
Read More