android-service verursacht ANR
Habe ich eine app, die von einer boot-Empfänger startet einen Dienst, der in regelmäßigen Abständen löscht Zeilen aus einer Tabelle auf dem Telefon Sqlite-DB. Den BootReceiver funktioniert einwandfrei. Der Dienst, der es erzeugt hat ein infinate loop, der angehalten ist, die von einem Thread.schlafen für 30 Sekunden(für die Prüfung), irgendwann ist es alle paar Stunden oder so. Es tut löschen Sie die Zeilen, aber ich bin nicht davon überzeugt, dass es alle 30 Sekunden und schließlich auch bewirkt es eine ANR. Die Art, wie es umgesetzt scheint ein wenig unausgereift. Gibt es einen besseren Weg, um das umzusetzen, was ich mache? Wenn nicht, wie kann ich verhindern, dass die ANR als ich dachte, die Dienstleistungen nicht zu den Asynchronen, nur Netzwerk Anrufe etc.
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyBootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent myIntent = new Intent(context, SendOutstandingTransactions.class);
myIntent.setAction("com.carefreegroup.startatboot.MyService");
context.startService(myIntent);
}
}
.
import org.joda.time.DateTime;
import android.app.Service;
import android.content.Intent;
import android.database.Cursor;
import android.os.IBinder;
import android.util.Log;
public class SendOutstandingTransactions extends Service {
private static final String TAG = SendOutstandingTransactions.class.getSimpleName();
NfcScannerApplication nfcscannerapplication;
Cursor c;
@Override
public void onCreate() {
Log.e(TAG, "inside onCreate of SendOutstandingTransactions");
nfcscannerapplication = (NfcScannerApplication)getApplication();
super.onCreate();
}
@Override
public void onDestroy() {
Log.e(TAG, "inside onDestroy of SendOutstandingTransactions");
super.onDestroy();
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.e(TAG, "inside onStart of SendOutstandingTransactions");
do{
DateTime now = new DateTime();
//nfcscannerapplication.loginValidate.deleteTransactionsOlderThanThreeDays(now);
nfcscannerapplication.loginValidate.deleteTableTransactions();
Log.e(TAG, "just called housekeeping method in service");
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}while(true);
}//end of onStart
@Override
public IBinder onBind(Intent intent) {
//TODO Auto-generated method stub
return null;
}
}
.
In der manifest -
<service android:name=".SendOutstandingTransactions" >
<intent-filter>
<action android:name="com.carefreegroup.startatboot.MyService" />
</intent-filter>
</service>
<receiver
android:name=".MyBootReceiver"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
[edit1]
Wie ich den Dienst starten
//get a Calendar object with current time
Calendar cal = Calendar.getInstance();
//add 5 minutes to the calendar object
cal.add(Calendar.MINUTE, 1);
Intent intent = new Intent(getApplicationContext(), AlarmReceiver.class);
intent.putExtra("alarm_message", "sending outstanding transactions");
//In reality, you would want to have a static variable for the request code instead of 192837
PendingIntent sender = PendingIntent.getBroadcast(getApplicationContext(), 192837, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//Get the AlarmManager service
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
//am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
//86400000 = 24 hours
//43200000 = 12 hours
//3600000 = 1hr
//1800000 = 30 mins
//600000 = 10 mins
//300000 = 5 mins
am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 300000 , sender);
den alarmReceiver
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
try {
Bundle bundle = intent.getExtras();
String message = bundle.getString("alarm_message");
//Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
Intent myIntent = new Intent(context, SendOutstandingTransactions.class);
myIntent.setAction("com.carefreegroup.rr3.startatboot.MyService");
context.startService(myIntent);
} catch (Exception e) {
Toast.makeText(context, "There was an error somewhere, but we still received an alarm", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}
den service
public class SendOutstandingTransactions extends IntentService {
private static final String TAG = SendOutstandingTransactions.class.getSimpleName();
instance variables
@Override
public void onCreate() {
super.onCreate();
}
@Override
protected void onHandleIntent(Intent intent) {
//do something
}//end of onHandleIntent
public SendOutstandingTransactions() {
super("SendOutstandingTransactions");
}
- Sie wollen wahrscheinlich verwenden Sie ein alarm statt.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Quelle: http://developer.android.com/reference/android/app/Service.html
Lösung:
Verschieben Sie den code in einem dafür vorgesehenen thread. Diese kann getan werden, indem man zum Beispiel die
AsyncTask
Klasse.