0

IntentService를 확장하는이 서비스가 있습니다.IntentService의 명확성

public class RefreshService extends IntentService { 

static final String TAG = "RefreshService"; 

public RefreshService() { 
    super(TAG); 
} 

@Override 
public void onCreate() { 
    super.onCreate(); 
    Log.d(TAG, "onCreated"); 
} 



@Override 
public void onDestroy() { 
    super.onDestroy(); 
    Log.d(TAG, "onDestroyed"); 
} 

@Override 
public IBinder onBind(Intent intent) { 
    return null; 
} 

@Override 
protected void onHandleIntent(Intent intent) { 

    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); 
    final String username = prefs.getString("username", "").trim(); 
    final String password = prefs.getString("password", "").trim(); 

    Log.d(TAG, "onDestroyeds"); 

    if (TextUtils.isEmpty(username) || (TextUtils.isEmpty(password))){ 
     Toast.makeText(this, "Please update your username and password", Toast.LENGTH_LONG).show(); 
     return; 
    } 

    // here code for fetching data and inserting into db. 

} 

}

설정이없는 대신 토스트 메시지되는 쇼, 나는 다음과 같은 오류가 발생합니다. onHandleIntent 방법의 코드가 다른 스레드에서 실행되는

  1. 나는 다음을 믿고있어

    07-12 18:28:33.125 2961-2961/com.example.krishna.yamba I/menu_item_selected﹕ [0,Refresh] 
    07-12 18:28:33.143 2961-2961/com.example.krishna.yamba D/RefreshService﹕ onCreated 
    07-12 18:28:33.147 2961-3637/com.example.krishna.yamba D/RefreshService﹕ onDestroyeds 
    07-12 18:28:33.147 2961-3637/com.example.krishna.yamba D/RefreshService﹕ onDestroyeds 
    07-12 18:28:33.181 2961-2961/com.example.krishna.yamba D/RefreshService﹕ onDestroyed 
    07-12 18:28:33.197 2961-3637/com.example.krishna.yamba W/MessageQueue﹕ Handler (android.view.ViewRootImpl$ViewRootHandler) {38f6505f} sending message to a Handler on a dead thread 
        java.lang.IllegalStateException: Handler (android.view.ViewRootImpl$ViewRootHandler) {38f6505f} sending message to a Handler on a dead thread 
          at android.os.MessageQueue.enqueueMessage(MessageQueue.java:325) 
          at android.os.Handler.enqueueMessage(Handler.java:631) 
          at android.os.Handler.sendMessageAtTime(Handler.java:600) 
          at android.os.Handler.sendMessageDelayed(Handler.java:570) 
          at android.os.Handler.post(Handler.java:326) 
          at android.view.ViewRootImpl.loadSystemProperties(ViewRootImpl.java:5413) 
          at android.view.ViewRootImpl.<init>(ViewRootImpl.java:378) 
          at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:253) 
          at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69) 
          at android.widget.Toast$TN.handleShow(Toast.java:414) 
          at android.widget.Toast$TN$1.run(Toast.java:322) 
          at android.os.Handler.handleCallback(Handler.java:738) 
          at android.os.Handler.dispatchMessage(Handler.java:95) 
          at android.os.Looper.loop(Looper.java:135) 
          at android.os.HandlerThread.run(HandlerThread.java:61) 
    

    사실이다.

  2. 따라서 여기에 집중적 인 작업을 수행하는 것이 좋습니다. (이 경우 방금 db 가져 오기 및 업데이트 중입니다)

설정이 올바른 경우 모든 것이 정상적으로 작동합니다. 그런 다음 가져 오기 및 업데이트에 비해 축배 메시지를 넣는 것이 문제가되지 않아야합니다.

설정이 비어있는 경우 축배 메시지를 넣는 방법은 무엇입니까?

+0

을 사용 : IntentServiceToast을 보여주기 위해, 당신은 같은 것을 할 필요가? 앱 내부의 사용자가 시작할 때만 실행됩니까? 또는 백그라운드에서 임의로 시작할 수 있습니까 (예 : AlarmManager)? – Karakuri

+0

실제로 두 방법 모두 –

답변

2

IntentServiceonHandleIntent을 별도의 스레드에서 실행합니다. 반면에 Toast은 메인/UI 스레드에서 실행됩니다. 어떻게이 서비스를

new Handler(Looper.getMainLooper()).post(new Runnable() {   
    @Override 
    public void run() { 
     Toast.makeText(RefreshService.this, "Toast msg here", Toast.LENGTH_LONG).show(); 
    } 
}); 
3

onHandleIntent 메서드의 코드가 다른 스레드에서 실행됩니다.

수정.

따라서 여기서는 집중적 인 작업을 수행하는 것이 좋습니다. (이 경우 방금 db 가져 오기 및 업데이트)

수정.

그런 다음 축하 메시지를 가져 와서 업데이트하는 것이 문제가되지 않아야합니까?

아니요, 배경 스레드에서 Toast을 사용할 수 없기 때문에 가능하지 않습니다. 사실, 오류가 당신에게 말하는 것입니다.

설정이 비어있는 경우 축배 메시지를 넣는 방법은 무엇입니까?

올바른 대답은 Toast을 사용하지 않는 것입니다. 이는 사용자에게 오류 상태를 알리는 두 번째 최악의 해결책입니다 (최악의 경우 사용자에게 전혀 말하지 않으려 고 함). Toast이 읽을 수있는 동안 사용자가 화면을 엿볼 수 있다는 보장은 없으므로 사용자는 메시지를 놓칠 수 있습니다. crouton 또는 무엇인가를 사용하십시오.

어쨌든 UI가 포 그라운드에있는 경우 UI를 업데이트하는 기본 응용 프로그램 스레드를 가져 오도록 정렬해야합니다. 이를 수행하기위한 현대적 솔루션은 일종의 이벤트 버스를 필요로합니다.세 가지 주요 이벤트 버스 구현은이 시간에 있습니다

내가 링크 샘플 애플리케이션 모두 UI 또는 Notification 패턴을 보여 주며, 우리가 전경에있을 경우 사용자 인터페이스를 업데이트하거나 Notification을 발생시켜 사용자가 이벤트에 대해 알 수 있도록합니다 포 그라운드에서 UI가 없습니다.

+1

EventBus에 투표하십시오. LBM은 동일한 프로세스에 있기 때문에 데이터 객체를 직렬화하는 것은 의미가 없으며 변경된 사항이 없다고 가정하면 Otto는 스레드 경계를 간단히 처리하지 않습니다. 우리는 배경 모범 사례를 현재 검토하고 있으므로, 나는 오토를 다시 살펴볼 필요가 있을지 모르지만 LBM은 우리 그룹과 함께 호의적이지 않습니다. 지금까지 EventBus는 특정 요청을 특정 Fractivity 인스턴스와 연관시키는 것을 제외하고는 훌륭했습니다. 그러나 나는 빗 나간다. –

+0

정말 아주 청초하고 상세한 답변. 하지만 디버깅 이해를 돕기 위해. 통나무가 물건들을 설명하고 있다고 했잖아. 하지만 여기서 정확히 알 수는 없습니다. 제발 로그에서 특정 수 있습니다. –

+0

@Napster : "로그에서 물건을 설명한다고 말했어"- 아닙니다. 내 대답에는 "로그"라는 단어가 표시되지 않습니다. – CommonsWare