Wenn ich ein Programm mit der Aufschrift "Wenn Sie die Starttaste von MainActivity drücken, wird der Dienst gestartet" erstellt habe, wurden jedes Mal mehrere Dienste gestartet, wenn Sie die Starttaste drücken! .. Es ist also eine Erinnerung daran, wie man doppelte Stiefel vermeidet.
Die Methode zur Verwendung der ActivityManager.RunningServiceInfo () -Methode scheint veraltet zu sein </ font>, und jede Methode von ActivityManager wird im Entwicklungsprozess wie dem Debuggen verwendet. Es war eine Referenz, es nicht in dem Code zu verwenden, der die fertige Anwendung ausführt. Ist es also sinnvoll, die ActivityManager-Methode nicht zu verwenden?
API26
** Hauptdateien **
MainActivity.java
MyService.java: erweitert den Service
MainActivity.java
■ Schaltfläche "Start". Klicken Sie auf "Ereignis":
Beziehen Sie sich auf die globale Variable MyServiceState von MyService.class und starten Sie MyService.java, wenn MyServiceState == false
■ Schaltfläche Stopp. Klicken Sie auf Ereignis: Führen Sie
stopService () aus, um MyService.class zu stoppen
** MyService.java **
Globale Variable: public static boolean Set MyServiceState = false;
When onCreate (): Ersetzen durch MyServiceState = true;
onStartCommand (): Protokoll ausführen ..
onDestroy (): Ersetzen durch MyServiceState = false;
■ Erklärung Deklarieren Sie globale und statische Variablen in MyService.class. Der Wert dieser Variablen bestimmt, ob der Dienst ausgeführt wird. Im folgenden Code wird die Variable auf einen booleschen Wert gesetzt. Wenn false, wird sie nicht gestartet, und wenn true, wird sie gestartet. Anhand des Werts der Variablen MyService.class aus ActivityMain.class wird beurteilt, ob der Dienst gestartet wurde oder nicht.
■ Bestätigung des Verhaltens Wenn Sie MyServiceState = false; </ font> in onCreate () von MyService.class festlegen, wird das Protokoll jedes Mal abgespielt, wenn Sie die Starttaste drücken. Mit MyServiceState = true; </ font> wird das Protokoll unabhängig davon, wie oft Sie die Starttaste drücken, nur einmal ausgeführt (wenn Sie die Stopptaste drücken, wird MyService erneut zerstört Sie können Log einmal mit der Starttaste spielen.
(Hinweis) API26 und höher stürzt ab, wenn der Dienst nicht ohne Benachrichtigung und startForeground () </ strong> Ausführung innerhalb von 5 Sekunden </ font> gestartet wird. Wenn Sie im folgenden Code die Benachrichtigung festlegen, ist der Code lang und schwer zu erkennen, sodass die Benachrichtigungsverarbeitung aufgrund von Abstürzen nicht ausgeführt wird. Dieser Code dient nur zur Überprüfung des Verhaltens, den Dienst nicht zweimal zu starten. Fügen Sie am Ende den Nicht-Absturzcode hinzu, der den API 16 bis 29 entspricht ([Beispielcode der residenten Anwendung, gezählt nach Protokoll]).
Damit beginnt der Code unten!
ActivityMain.java
ActivityMain.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn_start = findViewById(R.id.btn_start);
Button btn_stop = findViewById(R.id.btn_stop);
final Intent intent = new Intent(this,MyService.class);
btn_start.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
// MyService.Siehe die MyServiceState-Variable der Klasse
// MyServiceState=Wenn false, starten Sie den Service
if(MyService.MyServiceState == false){
startForegroundService(intent);
}
}
});
btn_stop.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
stopService(intent);
}
});
}
MyService.java
MyService.java
public class MyService extends Service {
//Deklarieren Sie die globale statische Variable MyServiceState mit dem Anfangswert false
// onCreate()Durch Ersetzen von true in
//Sie können feststellen, ob Service onCreate ist, indem Sie auf MyServiceState verweisen.
public static boolean MyServiceState = false;
public MyService() {
}
@Override
public void onCreate(){
super.onCreate();
//Setzen Sie den globalen statischen MyServiceState auf true
MyServiceState = true;
}
@Override
public int onStartCommand(Intent intent,int flags,int startId){
Log.d("Service","Started");
return START_NOT_STICKY;
}
@Override
public void onDestroy(){
super.onDestroy();
MyServiceState = false;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
Ziel-SDK td> | API29 td> |
Minimum SDK td> | API16 td> |
Manifest hinzugefügt td> | verwendet die Berechtigung android: name = "android.permission.FOREGROUND_SERVICE" td> |
Hauptdateien td> | MainActivity.java MyService.java td> |
Andere td> | Legen Sie den Benachrichtigungsinhalt fest. Das Benachrichtigungssymbol ist Ihre Wahl td> |
■ Erklärung Der folgende Code bestätigt im Gegensatz zum obigen Beispielcode die API-Version von 16 bis 29. Ich habe eine Benachrichtigung in den Benachrichtigungsbereich eingefügt, um einen Absturz zu verhindern.
Wenn Sie auf dem UI-Bildschirm auf Start drücken, wird eine Zählnachricht im Protokoll abgespielt, eine Stoppschaltfläche stoppt die Nachricht und Start spielt erneut eine Zählnachricht ab. Selbst wenn Sie die Starttaste kontinuierlich drücken, wird die Zählnachricht nicht dupliziert.
Dann, während kindisch (Schande) MainActivity.java
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn_start = findViewById(R.id.btn_start);
Button btn_stop = findViewById(R.id.btn_stop);
final Intent intent = new Intent(this,MyService.class);
//Start Knopf
//Starten Sie MyService, wenn der Status der MyService-Variablen false ist
btn_start.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
if(MyService.state == false){
if(Build.VERSION.SDK_INT >=26){
startForegroundService(intent);
}else{
startService(intent);
}
}
}
});
//Stopptaste
btn_stop.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
stopService(intent);
}
});
}
}
MyService.java
MyService.java
public class MyService extends Service {
//Variablen, die den Status des Threads bestimmen
//Thread startet, wenn das Signal wahr ist, stoppt, wenn falsch
//mit onCreate auf true und mit onDestroy auf false setzen
private boolean signal;
//Variable, die bestimmt, ob MyService gestartet werden soll
public static boolean state = false;
public MyService() {
}
@Override
public void onCreate(){
super.onCreate();
state = true;
}
@Override
public int onStartCommand(Intent intent,int flags,int startId){
//Benachrichtigungsinhalt erstellen und Benachrichtigungen ausgeben
Notification notification;
NotificationCompat.Builder builder = new NotificationCompat.Builder(this,"id");
Intent intentm = new Intent(this,MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intentm,0);
notification = builder.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("title")
.setContentText("text")
.setContentIntent(pendingIntent)
.build();
if(Build.VERSION.SDK_INT >=26){
int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel channel = new NotificationChannel("id","name",importance);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel);
startForeground(1,notification);
}else{
notification = builder.setPriority(NotificationCompat.PRIORITY_LOW).build();
NotificationManagerCompat managerCompat = NotificationManagerCompat.from(this);
managerCompat.notify(1,notification);
}//Dies ist der Benachrichtigungsausgabecode
signal = true;
startThread();
return START_NOT_STICKY;
}
//Thread, der weiterhin ausgeführt wird Protokoll
public void startThread(){
new Thread(new Runnable(){
@Override
public void run() {
int i=0;
//Läuft, bis das Signal bei onDestroy falsch ist
while(signal){
try {
sleep(1000);
Log.d("COUNT", String.valueOf(i));
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
}
}
}).start();
}
@Override
public void onDestroy(){
super.onDestroy();
//Thread-Stopp-Signal ausgeben
signal = false;
//Repräsentiert den inaktiven Status des Dienstes
state = false;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}