IntentService ne sera pas affiché Toast
-
27-10-2019 - |
Question
Ce IntentService je créé montrera Toasts dans onStartCommand () et OnDestroy (), mais pas dans onHandleIntent (). Suis-je manque quelque chose au sujet des limites d'un IntentService?
public class MyService extends IntentService {
private static final String TAG = "MyService";
public MyService(){
super("MyService");
}
@Override
protected void onHandleIntent(Intent intent) {
cycle();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show(); //This happens!
return super.onStartCommand(intent,flags,startId);
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
Toast.makeText(this, "service stopping", Toast.LENGTH_SHORT).show(); //This happens!
super.onDestroy();
}
private void cycle(){
Toast.makeText(this, "cycle done", Toast.LENGTH_SHORT).show(); //This DOESN'T happen!
Log.d(TAG,"cycle completed"); //This happens!
}
}
La solution
onHandleIntent () est appelée à partir d'un fil d'arrière-plan (qui est ce que IntentService est tout au sujet), de sorte que vous ne devriez pas faire l'interface utilisateur à partir de là.
Autres conseils
La réponse acceptée est incorrect.
Voici comment vous pouvez afficher des toasts de onHandleIntent()
:
Créer une classe DisplayToast :
public class DisplayToast implements Runnable {
private final Context mContext;
String mText;
public DisplayToast(Context mContext, String text){
this.mContext = mContext;
mText = text;
}
public void run(){
Toast.makeText(mContext, mText, Toast.LENGTH_SHORT).show();
}
}
instancier un Handler
dans le constructeur de votre service et appeler la méthode post
avec l'intérieur de l'objet DisplayToast
.
public class MyService extends IntentService {
Handler mHandler;
public MyService(){
super("MyService");
mHandler = new Handler();
}
@Override
protected void onHandleIntent(Intent intent) {
mHandler.post(new DisplayToast(this, "Hello World!"));
}
}
Vous devriez commencer le Toast sur le thread principal:
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
}
});
En effet, sinon le fil des démissions de IntentService avant le toast peut être envoyer, provoquant un IllegalStateException:
java.lang.IllegalStateException: Handler (android.os.Handler) {12345678} envoyer un message à un gestionnaire sur un fil mort
Une autre option est RxJava , par exemple:.
private void showToast(final String text) {
Observable.just(text)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Toast.makeText(getApplicationContext(), s, Toast.LENGTH_LONG).show();
}
});
}
caveat :. Je suis nouveau à Android