Почему пользовательский интерфейс перестает обновлять обратный отсчет после перезапуска приложения при использовании службы намерений? - PullRequest
1 голос
/ 05 мая 2020

Я пытаюсь показать обратный отсчет в текстовом окне от al oop внутри Intent Service. Я использую класс приемника результатов для связи между Intent Service и Activity. При первом запуске службы работает нормально. Текстовое представление показывает обратный отсчет для каждого запуска l oop в службе.

Но когда я закрываю и снова запускаю приложение, текстовое представление не показывает обратный отсчет и показывает только жестко закодированный текст, в то время как с другой стороны, сервисные кадры работают в фоновом режиме.

Вот мой фрагмент кода для MainActivity

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

 public static final String RECEIVER_INTENT_EXTRA_NAME = "message_receiver_intent_extra";
 private static final String TAG = "MainActivity";
 private Intent intent;
 MyIntentService myIntentService;
 public TextView serviceCountdown;
 private Button startButton, stopButton;
 private Handler handler;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    getSupportActionBar().hide();

    myIntentService = new MyIntentService();
    startButton = findViewById(R.id.startServiceButton);
    stopButton = findViewById(R.id.stopServiceButton);

    startButton.setOnClickListener(this);
    stopButton.setOnClickListener(this);

    handler = new Handler();
    serviceCountdown = findViewById(R.id.serviceCountdown);
    MessageReceiver messageReceiver = new MessageReceiver(handler);

    // send intent service
    intent = new Intent(this, MyIntentService.class);
    intent.putExtra(RECEIVER_INTENT_EXTRA_NAME, messageReceiver);

 }

 @Override
 public void onClick(View v) {

    if (startButton.equals(v)) {
        ContextCompat.startForegroundService(getApplicationContext(), intent);
    }
    if (stopButton.equals(v)){
        stopService(intent);
    }
 }

 public class MessageReceiver extends ResultReceiver {

    public MessageReceiver(Handler handler) {
        super(handler);
    }

    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) {
        super.onReceiveResult(resultCode, resultData);
        if (resultCode == 1 && resultData != null){
            final String countdown = resultData.getString("countdown");

            handler.post(new Runnable() {
                @Override
                public void run() {
                    serviceCountdown.setText(countdown);
                }
            });
        }
    }
 }
}

А вот мой код для Intent Service Class

public class MyIntentService extends IntentService {

private static final String CHANNEL_ID = "my_channel_id";
private static final String TAG = "MyIntentService";

public MyIntentService() {
    super("MyIntentService");
    setIntentRedelivery(true);
}

@Override
public void onCreate() {
    super.onCreate();

    Intent notificationIntent = new Intent(this, MainActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent,0);

    Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("My Service Title")
            .setContentText("This is sample notification text")
            .setSmallIcon(R.drawable.ic_battery)
            .setContentIntent(pendingIntent)
            .build();
    startForeground(1, notification);
}


@Override
protected void onHandleIntent(@Nullable Intent intent) {

    ResultReceiver resultReceiver = intent.getParcelableExtra(MainActivity.RECEIVER_INTENT_EXTRA_NAME);
    Log.d(TAG, "onHandleIntent: called");
    synchronized (this) {
        for (int i = 10; i >= 0; i--) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Log.d(TAG, "Service is looping : " + i);

            Bundle bundle = new Bundle();
            bundle.putString("countdown", String.valueOf(i));
            resultReceiver.send(1, bundle);
        }
    }
}

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

В реальном проекте я не собираюсь использовать l oop для отображения обратного отсчета. Это просто для целей тестирования и отладки.

1 Ответ

0 голосов
/ 05 мая 2020

Используйте Local Broadcast Receiver из вашей службы для активности. Теперь вы получаете ResultReceiver из намерения MainActivity. Когда деятельность уничтожена, намерения также уничтожаются. Используйте этот код широковещательного приемника в своем классе обслуживания.

LocalBroadcastManager localBroadcastManager = 
        LocalBroadcastManager.getInstance(this);
        Intent sendIntent = new Intent(INTENT_ACTION_KEY);
        sendIntent.putExtra(DATA_KEY, data);
        localBroadcastManager.sendBroadcast(sendIntent);

Включите этот локальный широковещательный приемник в свою деятельность.

  BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent != null) {
             //Perform your logic.
            }
        }
    };

Убедитесь, что вы зарегистрировали эту трансляцию, когда начинается действие, и отмените регистрацию, когда стоп.

 @Override
public void onStart() {
    super.onStart();

    LocalBroadcastManager.getInstance(this).registerReceiver((broadcastReceiver),
            new IntentFilter(INTENT_ACTION_KEY));
}

@Override
public void onStop() {
    LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
    super.onStop();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...