为什么在使用Intent服务时,重启应用后UI会停止更新倒计时?

问题描述 投票:0回答:1

我试图在Intent Service的循环中的textview中显示一个倒计时,我使用结果接收器类在Intent Service和Activity之间进行通信。我正在使用结果接收器类来实现Intent服务和Activity之间的通信。当我第一次启动服务时,工作正常。每次循环在服务中运行时,文本视图都会显示倒计时。

但当我关闭并再次启动应用程序时,文本视图不显示倒计时,只显示硬编码文本,而另一方面,服务在后台继续运行。

下面是我的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服务类的代码。

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();
}
}

在真正的项目中,我的目的不是使用循环来显示倒计时,而是为了测试和调试。它只是为了测试和调试的目的。

java android service android-service
1个回答
0
投票

使用本地广播接收器从你的服务到活动。现在你从MainActivity Intent中得到ResultReceiver。当活动被破坏时,意图也被破坏了。在你的服务类中使用这个广播接收器代码。

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

在你的activity中获取这个本地广播接收器。

  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();
}
© www.soinside.com 2019 - 2024. All rights reserved.