2012년 2월 19일 일요일

AppWidget 구현시 가장 중요한 것은?

AppWidget 구현 시 XXXConfigure, XXXProvider, Service 정말 많은 것을 구현해야 합니다.
그중에서도 Widget의 구성요소를 사용자로하여금 설정할 수 있게 해 주는 것이 XXXConfigure 인데요..

XXXConfigure를 만드는 순간 우리는 유령 Widget에 시달려야 합니다.

XXXConfigure는 Activity형태라는 것 다 아실테고..
User가 Activity를 빠져나가는 방법은 여러가지가 있을 수 있습니다.

1. home 버튼
2. back 버튼
3. 취소버튼 - 친절하게 XXXConfigure 화면에서 취소버튼을 만들은 경우
4. 그외 상상에 맞기겠습니다.

메뉴얼이나 developer site에 가서 보면

XXXConfigure내에서 Widget 만들기를 취소하는 것은 XXXConfigure에 setResult()에 RESULT_CANCELED를 setting하는 것으로 되어 있으나...아무리 이렇게 해봐도 유령은 계속 계속 생기게 됩니다.

현재 얼마나 많은 appWidget이 host에 등록 되어 있는지 대한 코드는 다음과 같습니다.

ComponentName compName = new ComponentName(this, XXXProvider.class);
int appWidgetIds[] = AppWidgetManager.getInstance(this).getAppWidgetIds(compName);
AppWidgetHost host = new AppWidgetHost(this, 0);

for(int i = 0; i < appWidgetIds.length; i++){
     Log.d(TAG, "[" + i + "] " + appWidgetIds[i]);
}

이코드를 XXXConfigure onCreate()에 넣어 보시면 현재 얼마나 많은 위젯들이 있는지 알 수 있겠죠.

유령은 XXXConfigure를 실행하고 setResult(RESULT_OK, intent); 가 호출되지 않은 상태인데요, 화면에 위젯이 표시되지 않고 host에 id로만 존재하는 놈을 말합니다.

그럼 어떻게 지울 수 있을까요....?

항상, onPause() 아니면 onDestroy()에서 (onPause()가 나을 것 같아요..) 유령을 찾아 지워야 합니다.

지우는 코드는 위에서 언급한 widgetId를 보는 코드와 동일합니다.

ComponentName compName = new ComponentName(this, XXXProvider.class);
int appWidgetIds[] =AppWidgetManager.getInstance(this).getAppWidgetIds(compName);
AppWidgetHost host = new AppWidgetHost(this, 0);

for(int i = 0; i < appWidgetIds.length; i++){
        Log.d(TAG, "[" + i + "] " + appWidgetIds[i]);
        if(appWidgetIds[i]가 유령입니까?){
              host.deleteAppWidgetId(appWidgetIds[i]);
        }else{
              // do nothing..
        }
}

빨간색으로 칠한 부분을 생각해 보겠습니다.

화면에 widget이 생성되어 있는지 아닌지 알아내는 방법을 못찾았습니다.(좀 알려주세요.)

그걸 안다면 이런짓을 하지는 않을 겁니다. 그러나 방법을 모르기에 제대로 생성된(즉, User가 XXXConfigure화면에서 OK버튼을 눌렀을때) widget과 아닌것을 구분하는 구분자 정도는 widget 생성시 만들어서 어디에 저장해 놓아야 합니다. 가장 편리하고 쉬운 것은 SharedPreferences를 이용하는 것입니다.

즉, 제대로된 생성된 appWidget의 경우, SharedPreferences 에 제대로 된놈인가를 표시하는 것이죠....

appWidgetIds[i] 가 유령인지 아닌지 판단시 SharedPreferences에 등록이 되어 있는지를 체크 하는 것입니다.

유령체크코드는 application마다 다르기에 여기서는 언급은 하지 않지만요...

조금은 지저분하고 googling을 해봐도 딱히 유령을 가장 깔끔하게 지우는 방법을 찾지는 못했습니다.

암튼 이만.... 댓글 달아 주시면 답변 드리겠습니다.



댓글 없음:

댓글 쓰기