我有一个前台服务,在其中需要检查我的活动是否正在运行。如果正在运行,请更新其UI,否则它应该不会崩溃。场景就像用户登录时一样,我正在启动一个前台服务,该服务为用户同步数据并不断更新多个活动的UI。我已经使用广播接收器在服务和活动之间建立了通信,但是一旦该应用被用户杀死并重新打开,我就跌破了异常
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.content.BroadcastReceiver.onReceive(android.content.Context, android.content.Intent)' on a null object reference
at android.support.v4.content.LocalBroadcastManager.executePendingBroadcasts(LocalBroadcastManager.java:313)
at android.support.v4.content.LocalBroadcastManager$1.handleMessage(LocalBroadcastManager.java:121)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6863)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
下面是MyActivity代码的示例:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import sample.androido.com.myapplication.R;
public class CreateForegroundServiceActivity extends AppCompatActivity {
TextView display;
BroadcastReceiver broadcastReceiver= new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case "CONNECTED":
display.setText("Service connected");
break;
}
}
};;
private boolean isReceiverRegistered = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_foreground_service);
Button startServiceButton = (Button)findViewById(R.id.start_foreground_service_button);
startServiceButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(CreateForegroundServiceActivity.this, MyForeGroundService.class);
intent.setAction(MyForeGroundService.ACTION_START_FOREGROUND_SERVICE);
startService(intent);
}
});
Button stopServiceButton = (Button)findViewById(R.id.stop_foreground_service_button);
stopServiceButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(CreateForegroundServiceActivity.this, MyForeGroundService.class);
intent.setAction(MyForeGroundService.ACTION_STOP_FOREGROUND_SERVICE);
startService(intent);
}
});
display = findViewById(R.id.display);
}
private void registerReceiver() {
if(!isReceiverRegistered){
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("CONNECTED");
LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver,intentFilter);
isReceiverRegistered = true;
}
}
private void unregisterReceiver() {
if(broadcastReceiver != null) {
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
broadcastReceiver = null;
isReceiverRegistered = false;
}
}
@Override
protected void onResume() {
super.onResume();
registerReceiver();
}
@Override
public void onPause() {
super.onPause();
unregisterReceiver();
}
}
下面是我的服务代码示例:
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ContentResolver;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioAttributes;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.widget.Toast;
import android.support.v4.app.NotificationCompat;
import sample.androido.com.myapplication.R;
public class MyForeGroundService extends Service {
private static final String TAG_FOREGROUND_SERVICE = "FOREGROUND_SERVICE";
public static final String ACTION_START_FOREGROUND_SERVICE = "ACTION_START_FOREGROUND_SERVICE";
public static final String ACTION_STOP_FOREGROUND_SERVICE = "ACTION_STOP_FOREGROUND_SERVICE";
public static final String ACTION_PAUSE = "ACTION_PAUSE";
public static final String ACTION_PLAY = "ACTION_PLAY";
public static final String PRIMARY_CHANNEL = "default";
public MyForeGroundService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG_FOREGROUND_SERVICE, "My foreground service onCreate().");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(intent != null)
{
String action = intent.getAction();
switch (action)
{
case ACTION_START_FOREGROUND_SERVICE:
startForegroundService();
Toast.makeText(getApplicationContext(), "Foreground service is started.", Toast.LENGTH_LONG).show();
break;
case ACTION_STOP_FOREGROUND_SERVICE:
stopForegroundService();
Toast.makeText(getApplicationContext(), "Foreground service is stopped.", Toast.LENGTH_LONG).show();
break;
}
}
return super.onStartCommand(intent, flags, startId);
}
/* Used to build and start foreground service. */
private void startForegroundService()
{
NotificationCompat.Builder mBuilder = notificationBuilder();
// Start foreground service.
startForeground(1, mBuilder.build());
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
Intent intent = new Intent();
intent.setAction("CONNECTED");
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
}
},100000);
}
private void stopForegroundService()
{
Log.d(TAG_FOREGROUND_SERVICE, "Stop foreground service.");
// Stop foreground service and remove the notification.
stopForeground(true);
// Stop the foreground service.
stopSelf();
}
public NotificationCompat.Builder notificationBuilder(){
NotificationCompat.Builder mBuilder= new NotificationCompat.Builder(this, PRIMARY_CHANNEL)
.setContentTitle("Dummy Title")
.setContentText("Dummy Message")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText("Big text Message"
))
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mBuilder.setSmallIcon(R.drawable.app_icon_white);
mBuilder.setColor(getResources().getColor(R.color.theme_color));
} else {
mBuilder.setSmallIcon(R.drawable.app_icon_white);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = getResources().getString(R.string.feroz_channel_name);
String description = getResources().getString(R.string.feroz_channel_description);
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(PRIMARY_CHANNEL, name, importance);
channel.enableLights(true);
channel.setLightColor(getResources().getColor(R.color.theme_color));
channel.enableVibration(true);
channel.setDescription(description);
NotificationManager notificationManager1 = getSystemService(NotificationManager.class);
notificationManager1.createNotificationChannel(channel);
}
Intent stopIntent = new Intent(this, MyForeGroundService.class);
stopIntent.setAction(ACTION_STOP_FOREGROUND_SERVICE);
PendingIntent stopPlayIntent = PendingIntent.getService(this, 0, stopIntent, 0);
mBuilder.addAction(R.drawable.ic_launcher_new,"Hang Up",stopPlayIntent);
Intent intent = new Intent(this, CreateForegroundServiceActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(pendingIntent);
mBuilder.setUsesChronometer(true);
return mBuilder;
}
}
我不确定为什么它崩溃了。是因为应用程序在后台而不在前台。或者这不是服务与活动之间进行交流的正确方式。