导致ANR的android服务

标签 android service broadcastreceiver

我有一个应用程序,它从启动接收器启动一项服务,该服务会定期从手机的 Sqlite 数据库表中删除行。 BootReceiver 工作正常。它实例化的服务有一个无限循环,由 Thread.sleep 暂停 30 秒(用于测试),最终它将被设置为每隔几个小时左右。它确实会删除行,但我不相信它是每 30 秒删除一次,并且最终会导致 ANR。它的全部实现方式似乎有点粗糙。有没有更好的方法来实现我正在做的事情?如果不是,我怎么能停止 ANR,因为我认为服务不必是异步的,只需网络调用等。

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;
    }

}

AndroidManifest 文件:

<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>

我如何启动服务

// 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);

报警接收器:

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();
 
    }
 }
 
}

服务:

 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");
            
        }

最佳答案

Note that services, like other application objects, run in the main thread of their hosting process. This means that, if your service is going to do any CPU intensive (such as MP3 playback) or blocking (such as networking) operations, it should spawn its own thread in which to do that work. More information on this can be found in Processes and Threads. The IntentService class is available as a standard implementation of Service that has its own thread where it schedules its work to be done.

来源:http://developer.android.com/reference/android/app/Service.html

解决方案:

将您的代码移至专用线程。这可以通过使用例如 AsyncTask 类来完成。

关于导致ANR的android服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12731139/

相关文章:

java - admob 智能横幅需要位于应用程序底部(通过 java)

android - 为什么BroadcastReceiver没有在后台运行?

java - 从一开始就立即调用第二个广播接收器?

android - NoClassDefFoundError 与 Kotlin 中的 ?.let{} block

java - Android Java 从列表中删除项目,过滤列表

c# - 从另一个 Controller 调用 WebApi Controller

web-services - 适合新手的实用 SOA

json - 从 Angular 2 中的 json 文件获取数据

java - 无法查看 fragment 内接收的短信

android - Activity 转换完成后播放音频