2012-09-13 5 views
3

this question을 확인했는데 내 문제에 대한 답을 찾지 못했지만 덜 복잡합니다. 내 메인 프로세스의 메뉴 항목에서 IntentService를 호출합니다. onHandleIntent()에 토스트를 올리는 스켈레톤입니다. 처리가 끝났을 때 잠깐 나타납니다. 그러나 화면에 영원히 남아 있습니다 (응용 프로그램이 중지 된 경우에도). 에뮬레이터와 갤럭시 S2를 모두 테스트하여 동일한 결과를 얻었습니다. 누군가 나를 올바른 방향으로 향하게 할 수 있습니까?Android : IntentService의 토스트가 영원히 화면에 남아 있습니다

package com.enborne.spine; 

import android.app.IntentService; 
import android.content.Intent; 
import android.util.Log; 
import android.widget.Toast; 

public class SaveFile extends IntentService { 
    private final String TAG = "SaveFile"; 

    public SaveFile() { 
     super("SaveFile"); 
    } 

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

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

    @Override 
    protected void onHandleIntent(Intent intent) { 
     // TODO Auto-generated method stub 
     Log.d(TAG, "HandleIntent"); 
     // File saved 
     Toast.makeText(this, "File has been saved", Toast.LENGTH_SHORT).show(); 
    } 
} 

합니다 (에서 onCreate 및들의 OnDestroy 재정의 그래서 무슨 일이 일어나고 있는지 볼 수 있습니다 Eclipse에서 로깅을 위해 일시적으로 만 존재한다.)

나는 메뉴에서 호출 :

서비스 코드 활동 따라서 (서비스가 시작되지 않았기 때문에 컨텍스트와의 간섭이 단지했다 - 어떤 바보가 매니페스트에 포함하는 것을 잊었다!) :

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    Intent i; 
    switch (item.getItemId()) { 
    case R.id.chart: 
     i = new Intent(getBaseContext(), Chart.class); 
     i.putExtra(KEY_CENTRE_LAT, mCentreLat); // centre coordinate 
     i.putExtra(KEY_CENTRE_LONG, mCentreLong); // centre coordinate 
     i.putExtra(KEY_RADIUS, mRadius); // effective radius 
     startActivity(i); 
     break; 

    case R.id.save: 
     Log.d("SaveFile", "Starting service..."); 
     //  i = new Intent(getBaseContext(), SaveFile.class); 
     i = new Intent(this, SaveFile.class); 
     startService(i); 
     break; 
    } 
    return true; 
} 

편집 : 내가 발견 this article, 이는 문제를 설명 할 수 있습니다. 한 문장을 인용하려면 :

그러나 토스트 메시지는 주 GUI 스레드에서만 사용할 수 있습니다. 그렇지 않으면 주 GUI 컨텍스트가 표시되지 않기 때문에 토스트 메시지가 사라지지 않는 문제가 발생합니다 별도의 스레드 컨텍스트에서 사용되는 토스트 메시지에 대해 아는 것).

+0

''onHandleIntent''가 여러 번 호출되는 것처럼 들리지만, LogCat에서이 경우가 있는지 확인할 수 있습니까? – harism

+0

메뉴 항목을 클릭 할 때만 한 번 호출됩니다. 또한 앱이 종료 된 후 앱이 어떻게 호출되는지 알 수 없습니다. 로그가 두 번 이상 호출 된 경우에도 로그에서 분명합니다 (위의 로그 코드 참조). –

+0

일단 우연히 렌더링 스레드 내에 토스트를 넣었던 것은 저에게 일어났습니다. 그것은 토스트가 대기열에 넣어지기 때문에 프로그램을 종료 한 후 내 토스트가 약 10 분 동안 표시되도록했습니다. 너는 예전처럼 토스트가 한 번만 나오고 10-100 번이 아닌지 확인하고 싶었다. – harism

답변

8

내 편집에 연결된 기사는 내 문제를 해결 한 this blog으로 안내했습니다. 다른 곳에서는 서비스에서 직접 건배를 할 수 없다는 것을 알지 못했습니다. 그래서 내 onHandleIntent 이제 다음과 같습니다

private Handler handler; 

@Override 
protected void onHandleIntent(Intent intent) 
{ 
    Log.d(TAG, "onHandleIntent"); 

    /* Stripped out some code here that I added later to keep it similar to 
    * my example above 
    */ 

    handler.post(new Runnable() 
    { 
//  @Override 
     public void run() 
     { 
      Toast.makeText(getApplicationContext(), "File has been saved", 
       Toast.LENGTH_SHORT).show(); 
     } 
    }); // Display toast and exit 
} 

(사람이 내가 실행에 @Override 주석했던 이유는() 오류를 피하기 위해 설명 할 수 있다면, 나는 감사하게 될 것입니다 몇 가지 다른 장소가있다. 내 응용 프로그램은 그 일을해야만했습니다.)

편집 : 사실상 똑같은 내용의 this post을 발견했습니다. 나는 그것을 전에 어떻게 놓쳤는 지 모른다.

+2

Java 5에서는 인터페이스에서 @Override를 사용할 수 없습니다. 자바 6에서 당신은 할 수있다. http://stackoverflow.com/questions/212614/should-a-method-that-implements-an-interface-method-be-annotated-withoverover –

2

onHandleIntent는 작업자 스레드에서 실행됩니다.

UI 스레드에서 Toast.show()를 실행하려고합니다.

+0

예 감사합니다 - 결국 거기에 있습니다! :) –

관련 문제