我刚刚开始学习编写服务昨天,在这里我有一个服务,我希望即使我的应用程序终止,所有的时间运行。此服务在我的Firebase数据库上具有侦听器,并在数据发生更改时生成通知。Android:关闭应用程序后服务崩溃
令我困惑的是我的服务只有在应用程序运行时才能成功运行。我关闭应用程序后立即通知我,“不幸的是,这个应用程序已停止(崩溃)”。警报来了两次,然后服务从未重新启动(我猜)。
我无法弄清楚为什么我的服务在关闭应用程序后崩溃。我在MainActivity的OnCreate方法中启动了服务。这里是整个服务类别:
public class MyService extends Service
{
private static DatabaseReference databaseReference;
private static String uid;
private static SharedPreferences sharedPreferences;
private static int notification_id=0;
private static boolean launched=false;
public MyService(){}
@Override public int onStartCommand(Intent intent, int flags, int startId)
{
if(!launched)
{
launched=true;
databaseReference=MainActivity.databaseReference;
uid=MainActivity.uid;
sharedPreferences=MainActivity.sharedPreferences;
databaseReference.child("users").child(uid).addValueEventListener(new ValueEventListener()
{
@Override public void onDataChange(DataSnapshot dataSnapshot)
{
MyData myData=dataSnapshot.getValue(MyData.class);
if(myData!=null)
{
ArrayList<String> myGroups=myData.getGroups();
for(String group_id:myGroups)
{
if(group_record_listener!=null)databaseReference.child("group_records").child(group_id).removeEventListener(group_record_listener);
databaseReference.child("group_records").child(group_id).addValueEventListener(group_record_listener);
}
}
}
@Override public void onCancelled(DatabaseError databaseError)
{
System.out.println(databaseError.getMessage());
}
});
}
return START_STICKY;
}
private ValueEventListener group_record_listener=new ValueEventListener()
{
@Override public void onDataChange(DataSnapshot dataSnapshot)
{
final String group_id=dataSnapshot.getKey();
Query lastQuery=databaseReference.child("group_records").child(group_id).child("records").orderByKey().limitToLast(1);
lastQuery.addListenerForSingleValueEvent(new ValueEventListener()
{
@Override public void onDataChange(DataSnapshot dataSnapshot)
{
for(DataSnapshot childSnapshot:dataSnapshot.getChildren())
{
final Record new_record=childSnapshot.getValue(Record.class);
if(new_record!=null)
{
if((new_record.getType()==1)&&new_record.getTo_name().equals(sharedPreferences.getString("name","")))
{
if(group_record_listener!=null)databaseReference.child("group_records").child(group_id).removeEventListener(group_record_listener);
}
if(!new_record.getOperator().equals(sharedPreferences.getString("name","")))
{
databaseReference.child("groups").child(group_id).child("name").addListenerForSingleValueEvent(new ValueEventListener()
{
@Override public void onDataChange(DataSnapshot dataSnapshot)
{
String group_name=(String)dataSnapshot.getValue();
generateNotification(new_record,group_name);
}
@Override public void onCancelled(DatabaseError databaseError){}
});
}
}
}
}
@Override public void onCancelled(DatabaseError databaseError){}
});
}
@Override public void onCancelled(DatabaseError databaseError)
{
System.out.println(databaseError.getMessage());
}
};
private void generateNotification(Record record,String group_name)
{
String str="";
switch (record.getType())
{
//. . . determine str
}
Notification notification=new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("group \""+group_name+"\"")
.setContentText(str)
.setWhen(System.currentTimeMillis())
.build();
NotificationManager manager=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
notification_id++;
manager.notify(notification_id,notification);
}
@Override public IBinder onBind(Intent intent)
{
return null;
}
}
如果您有任何想法,请帮助。在此先感谢~~
谢谢你的详细解释〜我很快就会查找FCM消息。但除此之外,我不知道是否有任何方法来保持uid值并将其传递给新的服务实例? – Einsambr
@Einsambr:代替MainActivity上的静态成员,将用于'startService()'的Intent中需要的数据传递给'onStartCommand()'的参数。 'Service'扩展了'Context',所以你可以'getSharedPreferences()'并且不需要在意图中传递它们。而不是START_STICKY。我想你想在服务重新启动时返回[START_REDELIVER_INTENT](https://developer.android.com/reference/android/app/Service.html#START_REDELIVER_INTENT)以再次导致包含启动数据的意图。 –