为什么UI在使用intent service的时候重启应用后倒计时就停止了?
Why does the UI stop updating countdown after restarting the app while using intent service?
我正在尝试通过 Intent 服务内的循环在文本视图中显示倒计时。我正在使用结果接收器 class 进行 Intent Service 和 Activity 之间的通信。当我第一次启动服务时它工作正常。文本视图显示服务中每次循环运行的倒计时。
但是当我关闭并再次启动该应用程序时,textview 不显示倒计时,只显示硬编码文本,而另一方面,服务仍然在后台运行。
这是我的主要代码片段Activity
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 服务代码 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();
}
}
在实际项目中,我的意图不是用循环来显示倒计时。它仅用于测试和调试目的。
从您的服务中使用本地广播接收器 activity。现在您从 MainActivity Intent 获得了 ResultReceiver。当 activity 被销毁时,意图也被销毁。
在您的服务中使用此广播接收器代码 class.
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.
}
}
};
确保在 activity 开始时注册此广播并在停止时取消注册。
@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();
}
我正在尝试通过 Intent 服务内的循环在文本视图中显示倒计时。我正在使用结果接收器 class 进行 Intent Service 和 Activity 之间的通信。当我第一次启动服务时它工作正常。文本视图显示服务中每次循环运行的倒计时。
但是当我关闭并再次启动该应用程序时,textview 不显示倒计时,只显示硬编码文本,而另一方面,服务仍然在后台运行。
这是我的主要代码片段Activity
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 服务代码 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();
}
}
在实际项目中,我的意图不是用循环来显示倒计时。它仅用于测试和调试目的。
从您的服务中使用本地广播接收器 activity。现在您从 MainActivity Intent 获得了 ResultReceiver。当 activity 被销毁时,意图也被销毁。 在您的服务中使用此广播接收器代码 class.
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.
}
}
};
确保在 activity 开始时注册此广播并在停止时取消注册。
@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();
}