Android Service 질문 요약

4854 단어
주로 Android Service 개발 과정에서 발생한 문제를 정리하여 2018-06-26 업데이트를 진행합니다.
1. Service Intent must be explicit
  • setaction 암시 호출, 이 방법은android5.0 이전 환경,android5.0 이후에 반드시 표시해야 할 호출 서비스입니다. 이 정의 action 방법은 서비스 Intent must be explicit 오류가 발생하기 때문에 호출을 표시해야 합니다. 아래 방법을 보십시오.
    //       service Intent
    final Intent it = new Intent(    .this,    Service  .class);   
    

  • 2. ServiceConnection/onServiceDisconnected에 해당되지 않음
  • ServiceConnection 이 방법은bindService 방식으로 서비스를 시작할 때 귀속된 후에 되돌아오는 리셋이지만 OnBind () 방법에서는 Ibinder 실례를 되돌려야 합니다. 그렇지 않으면 onServiceConnected 방법이 호출되지 않습니다.
  • onServiceDisconnected 이 방법은 이 서비스를 비정상적으로 종료할 때 이 리셋을 호출한다고 합니다.예를 들어 휴대전화 메모리가 충분하지 않아서 이 서비스를 회수했다.
  • 콜백의 전제는 Ibinder의 실례를 되돌리는 것이다. 그 중에서 두 가지 상황이 있다.
  • 첫 번째 서비스와Activity 간의 호출은 AIDL을 통해AIDL을 통해activity와의 인터페이스를 정의한 다음에 이 인터페이스의 실례를 되돌려준다.//TODO, 왜 aidl 실례로 돌아가면 좋은지 잘 몰라
  • 두 번째 서비스와Activity 사이는 하나의 프로세스 사이이므로 aidl을 사용하지 않지만 Binder의 실례를 되돌려야 한다. 실체 클래스를 써서 Binder를 계승한 다음에 이 클래스에서 구체적으로 호출하고자 하는 방법을 실현하고 OnServiceConnection의 반환이 성공할 때 서비스를 실체 클래스의 대상으로 강제로 전환한 다음에 대상의 방법을 호출할 수 있다.
  • public class RemoteCallbackImpl extends Binder {
      /**
       * TAG
       */
      private static final String TAG = "RemoteCallbackImpl";
      /**
       * BleServiceManage   
       */
      private BleServiceManager mBleServiceManager;
    
      /**
       *     
       *
       * @param mBleServiceManager bleServiceManager     
       */
      public RemoteCallbackImpl(BleServiceManager mBleServiceManager) {
          Log.e(TAG, "   Service         ");
          this.mBleServiceManager = mBleServiceManager;
      }
    
      /**
       *       
       *
       * @param enable   /  
       * @throws RemoteException   
       */
      public void setBleEnable(boolean enable) throws RemoteException {
          Log.e(TAG, "setBleEnable: " + "======== Ble  ========, enable: " + enable);
          mBleServiceManager.printfLog();
      }
    
      /**
       *     
       */
      private final ServiceConnection mServiceConnection = new ServiceConnection() {
          @Override
          public void onServiceConnected(ComponentName name, IBinder service) {
              Log.e(TAG, "onServiceConnected: " + "BleServiceImpl connected");
              mRemoteBinder = (RemoteCallbackImpl) service;
    
    
              if (mConnListener != null) {
                  mConnListener.onServiceConnected();
              }
          }
    
          @Override
          public void onServiceDisconnected(ComponentName name) {
              Log.e(TAG, "onServiceConnected: " + "BleServiceImpl disConnected");
              if (mConnListener != null) {
                  mConnListener.onServiceDisconnected();
              }
          }
      };
    
      @Override
      public void enable(boolean result) {
          try {
              mRemoteBinder.setBleEnable(result);
          } catch (RemoteException e) {
              e.printStackTrace();
          }
      }
    

    3. 서비스에서 스레드 생성
  • Service에서는HandlerThread 스레드만 생성할 수 있으며//TODO는 검증을 기다리고 있으며 15초 이상 지연될 수 없음
  • 이 스레드를 만들 때 이 스레드의 이름을 붙일 수 있고, 이 스레드를Messager의 대상에 봉하여 다른 대상의 시간 처리를 이 스레드에 집중시켜 처리하면 코드 논리를 더욱 명확하게 할 수 있다.
  • 그러나 이 HandlerThread 스레드를 만든 후에는 다음을 주의해야 합니다.
  • 우선 호출이 필요합니다.start () 방법으로 시작할 수 있습니다.
  • 그 다음으로 이 라인은 하나의handler 클래스에 의존하거나 하나의handler에서 다른handlerMessage 방법을 다시 써서 다른 대상이 이 라인에 보낸 이벤트를 처리해야 하며 이 라인에서 시간 소모 조작을 할 수 있다.
  • 셋째, 이 라인은 getLooper() 방법을 사용하여 이 라인의 생명 주기를 무한 순환 상태에서 통과할 수 있도록 해야 한다.quit() 메서드가 종료됩니다.
  • 넷째, 현재의 라인이handlerThread 라인인지 판단하려면 Log를 치고Thread를 통과할 수 있다.currentThread().getName () 과 getId () 등 방법으로 라인의 이름과 Id를 가져옵니다.
  • 다섯째, 라인이 끝나기 전에handler를 통과할 수 있다.hasMessage(int what) 방법으로 현재 Message가 존재하는지 판단하고handler를 통해 판단합니다.removeMessage(int what) 가 메시지를 삭제합니다.

  • handler를 직접 만들고handler에서 만든HandlerThread 루틴에 getLooper () 방법을 호출합니다
          mHandlerThread = new HandlerThread("check-message-coming");
          mHandlerThread.start();
    
          mThreadHandler = new Handler(mHandlerThread.getLooper()) {
              @Override
              public void handleMessage(Message msg) {
                  Log.e(TAG, "handleMessage: " + Thread.currentThread().getName() + " id: " + Thread.currentThread().getId());
                  if (isUpdateInfo) {
                      mThreadHandler.sendEmptyMessage(MSG_UPDATE_INFO);
                  }
              }
          };
    
  • 새로운 클래스를 만듭니다. 이 클래스는Handler 방법을 계승하고 HanderMessage를 다시 쓰는 방법입니다. 그러나 슈퍼(thread.getlooper () 를 직접 호출하여looper
    public class BleMsgHandler extends Handler {
        private HandlerThread mHandlerThread = null;
        ...
        //     
        public BleMsgHandler(Context mContext, HandlerThread mHandlerThread) {
          super(mHandlerThread.getLooper());  //   getlooper
          this.mContext = mContext;
          this.mHandlerThread = mHandlerThread;
        }
    }
    
  • 를 얻을 수 있습니다

    좋은 웹페이지 즐겨찾기