我剛剛開始學習編寫服務昨天,在這裏我有一個服務,我希望即使我的應用程序終止,所有的時間運行。此服務在我的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)以再次導致包含啓動數據的意圖。 –