我试图在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();
}
}
在真正的项目中,我的目的不是使用循环来显示倒计时,而是为了测试和调试。它只是为了测试和调试的目的。
使用本地广播接收器从你的服务到活动。现在你从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();
}