2012-01-20 6 views
1

私の目的は、デバイスの画面状態の変更をリッスンする(オンまたはオフ)サービスを開始し、その変更に基づいて動作させることです。私はこれが理想的ではないことを認識していますが、それにもかかわらず、それは私が達成しようとしているものです。ブロードキャストレシーバのサービスでのANR問題

何らかの理由で、私の放送受信機は、画面が表示されたときにのみ起動するように見えますが、画面が消灯したときには起動しません。さらに、logcatは多数のANRを明らかにし、サービスが繰り返し強制終了され、再起動されているように見えます。

私が見つかりました。チュートリアルの後:ここでhere

を私の関連するコードです:

ScreenReceiver.java

public class ScreenReceiver extends BroadcastReceiver { 

     private boolean screenOff; 

     @Override 
     public void onReceive(Context context, Intent intent) { 
      if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { 
       screenOff = true; 
      } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { 
       screenOff = false; 
      } 
      Intent i = new Intent(context, UpdateService.class); 
      i.putExtra("screen_state", screenOff); 
      context.startService(i); 
     } 

    } 

UpdateService.java(提案ごとに更新、今フォース閉じるの原因は)

public class UpdateService extends IntentService { 

     public UpdateService(String name) { 
     super(name); 
     // TODO Auto-generated constructor stub 
    } 

     @Override 
     public void onCreate() { 
      super.onCreate(); 
      // register receiver that handles screen on and screen off logic 
      IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON); 
      filter.addAction(Intent.ACTION_SCREEN_OFF); 
      BroadcastReceiver mReceiver = new ScreenReceiver(); 
      registerReceiver(mReceiver, filter); 
     } 

     @Override 
     protected void onHandleIntent(Intent intent) { 
      boolean screenOn = intent.getBooleanExtra("screen_state", false); 
      if (!screenOn) { 



       String command8 = "*******"; 
       String command9 = "*********"; 
        int timeout = 5; 

    try { 
    RootTools.Result result = new RootTools.Result() { 
    @Override 
    public void process(String line) throws Exception { 
    // Do something with current line; 
    // Maybe store it using setData() 
    } 

    @Override 
    public void onFailure(Exception ex) { 
    // Do something if we failed while trying to run a command or read its output 

    setError(1); 
    } 

    @Override 
    public void onComplete(int diag) { 


    } 

    }; 

    RootTools.sendShell(
    new String[] { 

    command8, 
    command9}, 
    timeout, 
    result 
    ); 
    if(0 != result.getError()) 
    return; 
    //Do something with getData() if needed. 
    } catch (IOException e) { 
    //Handle exception 
    } catch (InterruptedException e) { 
    //Handle exception 
    } catch (RootToolsException e) { 
    //TODO Auto-generated catch block 
    e.printStackTrace(); 
    } 

      } else { 

      String command8 = "*******"; 
       String command9 = "*******"; 
       String command10 = "********"; 
        String command11 = "********"; 
        int timeout = 5; 

    try { 
    RootTools.Result result = new RootTools.Result() { 
    @Override 
    public void process(String line) throws Exception { 
    // Do something with current line; 
    // Maybe store it using setData() 
    } 

    @Override 
    public void onFailure(Exception ex) { 
    // Do something if we failed while trying to run a command or read its output 

    setError(1); 
    } 

    @Override 
    public void onComplete(int diag) { 
    //TODO 

    } 

    }; 

    RootTools.sendShell(
    new String[] { 

    command8, 
    command9, 
    command10, 
    command11}, 
    timeout, 
    result 
    ); 
    if(0 != result.getError()) 
    return; 
    //Do something with getData() if needed. 
    } catch (IOException e) { 
    //Handle exception 
    } catch (InterruptedException e) { 
    //Handle exception 
    } catch (RootToolsException e) { 
    //TODO Auto-generated catch block 
    e.printStackTrace(); 
    } 
      } 
     } 

     @Override 
     public IBinder onBind(Intent arg0) { 
      // TODO Auto-generated method stub 
      return null; 
     } 

} 

ブロードキャスト受信者はstaですこのコードで、ボタンを押すことにより、RTED:

IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON); 
    filter.addAction(Intent.ACTION_SCREEN_OFF); 
    BroadcastReceiver mReceiver = new ScreenReceiver(); 
    registerReceiver(mReceiver, filter); 

答えて

3

onStart()は単に非推奨されていませんが、メインアプリケーションスレッドで呼び出されます。 ANRの定義は、メインアプリケーションスレッドに時間をかけ過ぎていることです。 onStart()ロジックをバックグラウンドスレッドに移動してください。恐らくIntentServiceをサブクラス化し、ロジックをonHandleIntent()に入れてください。

+0

すばやく有益な回答をいただきありがとうございます。私はあなたの提案(上記のオリジナルポストで編集されたコード)を実装しようとしましたが、受信者が登録された時点でForce Closeを取得しています。私が間違っていることに関するアイデアは? –

+0

@FrankBozzo:Eclipseで 'adb logcat'、DDMS、またはDDMSパースペクティブを使ってLogCatを調べ、" Force Close "に関連するスタックトレースを調べます。 – CommonsWare

+0

@FrankBozzo:あなたのサービスから 'onCreate()'を削除してください。なぜコードがそこに属していると思いますか? – CommonsWare