Android背景服务与背景线程导致anr错误

时间:2015-03-16 23:37:54

标签: android

我已经实现了一个执行以下长操作的Android服务

  1. 当屏幕熄灭时开始记录加速度计数据。
  2. 当数据达到3000个样本时,我将其写入文件。
  3. 然后我对读取后的记录数据进行数据处理。
  4. 然后我从该数据中提取步态模板。
  5. 然后我计算相似度得分。
  6. 只要用户明确不退出此服务,我就希望该服务继续运行。
  7. 如果屏幕亮起,我会停止数据记录,并检查样本数是否超过最小样本数量,重复步骤2-5。否则只是删除记录的样本。

    我有一个广播接收器来获取SCREEN_ON和SCREEN _OFF广播写入文件工作正常但参与的时间是功能(或模板生成)我从android文档中读取

      

    服务在其托管进程的主线程中运行 - 该服务不会创建自己的线程,也不会在单独的进程中运行(除非您另行指定)。这意味着,如果您的服务要进行任何CPU密集型工作或阻止操作(例如MP3播放或网络),您应该在服务中创建一个新线程来完成这项工作。通过使用单独的线程,您将降低应用程序无响应(ANR)错误的风险,并且应用程序的主线程可以保持专用于用户与您的活动的交互。

    因此我试图用后台线程实现服务。但是我仍然得到任何帮助的错误吗?

    public class GaitAuthenticationService extends Service {
    
    int mStartMode;       // indicates how to behave if the service is killed
    IBinder mBinder;      // interface for clients that bind
    boolean mAllowRebind; // indicates whether onRebind should be used
    private int serviceState = 0; // This will maintain state of our service
    private BroadcastReceiver screenOnOffReceiver = new ScreenOffBroadCastReciever();;
    private SensorManager mSensorManager;
    private PowerManager mPowerManager;
    private PowerManager.WakeLock mLock;
    private AccelRecorderTesting mAccelRecorder;
    private Context context;
    private boolean screenOff;
    private KeyguardManager keyGaurdManager;
    private boolean screenState;
    private IntentFilter mfilter;
    
    private Looper mServiceLooper;
      private ServiceHandler mServiceHandler;
    
    
      // Handler that receives messages from the thread
      private final class ServiceHandler extends Handler {
          public ServiceHandler(Looper looper) {
              super(looper);
          }
    
    
          @Override
          public void handleMessage(Message msg) {
              // Normally we would do some work here, like download a file.
              // For our sample, we just sleep for 5 seconds.
    
    
    
              // Stop the service using the startId, so that we don't stop
              // the service in the middle of handling another job
    
              if (screenState==true && (keyGaurdManager.isKeyguardLocked() || keyGaurdManager.isKeyguardSecure())){
                  Log.d("SCREEN ON OFF RECIEVER","screen is oFF(onStartCommand)");
                  Log.d("GaitAuthenticationService", "Started recording data");
                  // For each start request, send a message to start a job and deliver the
                  // start ID so we know which request we're stopping when we finish the job
                  mAccelRecorder.onStartButtonIsClicked();    
    
              }
    
    
    
             // stopSelf(msg.arg1);
          }
      }
    
    
    @Override
    public void onCreate() {
    
        mAccelRecorder = new AccelRecorderTesting();
        keyGaurdManager = (KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE);
        mAccelRecorder = new AccelRecorderTesting(this.getApplicationContext());
        Log.i("GaitAuthenticationService", " is started");
    
        mfilter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
        mfilter.addAction(Intent.ACTION_SCREEN_ON);
        registerReceiver(screenOnOffReceiver, mfilter);
    
         // Start up the thread running the service.  Note that we create a
        // separate thread because the service normally runs in the process's
        // main thread, which we don't want to block.  We also make it
        // background priority so CPU-intensive work will not disrupt our UI.
        HandlerThread thread = new HandlerThread("ServiceStartArguments",new Process().THREAD_PRIORITY_BACKGROUND);
        thread.start();
    
        // Get the HandlerThread's Looper and use it for our Handler
        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }
    @SuppressLint("NewApi")
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    
    
    
    
        // The service is starting, due to a call to startService()
    //  if(intent!=null){
            //screenOnOffReceiver = new ScreenOffBroadCastReciever();
    
             screenState   = intent.getBooleanExtra("screen_state",screenOff);
            // For each start request, send a message to start a job and deliver the
            // start ID so we know which request we're stopping when we finish the job
            Message msg = mServiceHandler.obtainMessage();
            msg.arg1 = startId;
            if (screenState){
            mServiceHandler.sendMessage(msg);
            }
    
             if(screenState == false){
                  Log.d("SCREEN ON OFF RECIEVER","screenON(onStartCommand)");
                  try {
                      mAccelRecorder.onStopButtonIsClicked(true);
                  } catch (InterruptedException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  } catch (IllegalArgumentException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  } catch (FileNotFoundException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  } catch (IOException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
                  Log.d("GaitAuthenticationService", "Stop Recording data");
              }
    
    
    //  }
    
        return GaitAuthenticationService.START_STICKY;
    }
    
    @Override
    public IBinder onBind(Intent intent) {
    
        return null;
    }
    
    @Override
    public void onDestroy() {
        Log.i(" GaitAuthenticationService", "Service is destroyed");
        if(screenOnOffReceiver!=null){
            Log.i("screenreciever", "true");
            unregisterReceiver(screenOnOffReceiver);
            screenOnOffReceiver=null;
        }
        super.onDestroy();
    }
    /* (non-Javadoc)
     * @see android.app.Service#onUnbind(android.content.Intaent)
     */
    @Override
    public boolean onUnbind(Intent intent) {
        if(screenOnOffReceiver!=null){
            Log.i("screenreciever", "true");
            unregisterReceiver(screenOnOffReceiver);
            screenOnOffReceiver = null;
        }
    
        return super.onUnbind(intent);
    }
    

    }

    这是我的广播接收器

    public class ScreenOffBroadCastReciever extends BroadcastReceiver {
    
    private boolean screenOff;
    
    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent!=null){
            if ((intent.getAction().equals(Intent.ACTION_SCREEN_OFF))) {
    
    
                    screenOff = true;
    
            }
            if(intent.getAction().equals(Intent.ACTION_SCREEN_ON)){
                screenOff = false;
            }
    
        Intent i = new Intent(context, GaitAuthenticationService.class);
        i.putExtra("screen_state", screenOff);
        context.startService(i);
        }
    }
    

    }

    AndroidManifest.xml中的Receiver

    <receiver android:name="ScreenOffBroadCastReciever" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                 <action android:name="android.intent.action.SCREEN_OFF"/>
                 <action android:name="android.intent.action.SCREEN_ON"/>
            </intent-filter>
        </receiver>
    

0 个答案:

没有答案