2012-01-20 89 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

感謝您提供快速和翔實的答案。我試圖實施你的建議(代碼在上面的原始文章中編輯過),但是現在當接收機被註冊時就會強制關閉。關於我做錯什麼的想法? –

+0

@FrankBozzo:在Eclipse中使用'adb logcat',DDMS或DDMS透視圖來檢查LogCat並查看與「強制關閉」相關的堆棧跟蹤。 – CommonsWare

+0

@FrankBozzo:請從您的服務中刪除'onCreate()'。我不知道你爲什麼認爲代碼屬於那裏。 – CommonsWare