2 votes

L'activité se fige lors de l'exécution du service

J'ai un bouton qui, lorsqu'il est pressé, lance un service. Ce service commence à enregistrer les informations de l'appareil. Cependant, lorsque j'appuie sur le bouton de lancement, l'écran se fige temporairement pendant environ 8 secondes pendant qu'il enregistre les informations, puis, une fois que c'est terminé, l'écran se dégèle, un message de toast s'affiche (qui est censé s'afficher dès que vous appuyez sur le bouton) et ensuite je peux faire ce que je veux. Si je reviens à l'écran de l'application, lorsque l'application est en train de s'enregistrer (remarque : le service est toujours en cours d'exécution, ce qui ne la fige pas, mais seulement l'enregistrement), l'activité se fige à nouveau et ne me laisse rien faire tant que l'enregistrement n'est pas terminé.

J'ai essayé les asynctasks et l'exécution sur un nouveau thread exécutable/nouveau thread mais rien de tout cela n'a semblé fonctionner pour moi. Je ne sais pas si je les applique correctement ou non, mais j'aimerais résoudre le problème.

Voici mon onStartCommand dans la classe de service :

    @Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // THIS WOULD BE THE METHOD THAT RUNS WHATEVER YOU WANT TO DO EVERY SO OFTEN SO FOR ME THIS IS GETTING ALL DATA ETC
    getProcessInfo();

    //  LOG DELAY = SECONDS BETWEEN RUNNING SERVICE/METHOD. SET AT THE TOP
    myPendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    Alarmmgr.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+LOG_DELAY*1000, myPendingIntent);
    Intent notificationIntent = new Intent(this, LogOrCheck.class);
    PendingIntent contentIntent = PendingIntent.getActivity(this,
            101, notificationIntent,
            PendingIntent.FLAG_NO_CREATE);

    NotificationManager nm = (NotificationManager) this
            .getSystemService(Context.NOTIFICATION_SERVICE);

    Resources res = this.getResources();
    Notification.Builder builder = new Notification.Builder(this);

    builder.setContentIntent(contentIntent)
                .setSmallIcon(R.drawable.arrow_up_float)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.arrow_down_float))
                .setWhen(System.currentTimeMillis())
                .setAutoCancel(true)
                .setContentTitle("Androigenius")
                .setContentText("Service running OK");
    Notification n = builder.getNotification();

    startForeground(100, n);
    return Service.START_STICKY;
}

Et c'est ici que j'appelle startService :

but1.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {

            if (isClicked) {
                Context context = getApplicationContext();
                Toast toast = Toast.makeText(context, "Please press 'MINIMIZE' at the top to continue logging.", Toast.LENGTH_LONG);
                toast.setGravity(Gravity.TOP|Gravity.RIGHT, 10, 55);
                toast.show();
                System.out.println("Start logging");
                but1.setText("Stop Logging");
                but1.setTextColor(Color.RED);
                // START SERVICE, DONE. (STOP IS BELOW).
                startService(myIntent);
                isClicked = false;
            } 
            else if (!isClicked) {
                System.out.println("Stop Logging");
                but1.setText("Start Logging");
                // STOP SERVICE, DONE.
                stopService(myIntent);
                but1.setTextColor(getResources().getColor(color.cornblue));
                isClicked = true;
            }

1voto

Matthew Points 751

Les services sont exécutés sur le thread de l'interface utilisateur, ce qui provoque le "gel". L'utilisation d'un IntentService permet de créer un service qui s'exécute automatiquement en arrière-plan, et non sur le fil d'exécution de l'interface utilisateur. Voici quelques détails sur la classe IntentService :

Classe IntentService

0voto

Jiyong Park Points 634

Par défaut, le service s'exécute également dans le thread principal de votre application, dans lequel se déroulent les opérations de l'interface utilisateur. Par conséquent, si vous effectuez une tâche longue dans votre méthode onStartCommand(), cela bloquera le thread principal.

Pour éviter ce problème, vous devez migrer la tâche de journalisation dans un thread séparé. Vous pouvez utiliser la classe AsycTask pour ce faire. Veuillez vous référer à http://developer.Android.com/reference/Android/os/AsyncTask.html pour savoir comment utiliser cette classe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X