如何在Android中以块方法停止服务?

时间:2015-11-13 02:15:46

标签: android

  1. 我运行代码并获得以下结果,但我希望应用程序可以按顺序运行" A" - > " Service OnDestroy" - > " B" - > " C",我该怎么办?

  2. 我的方式2 部分,我尝试将代码放入函数new Handler().postDelayed(new Runnable() {},它没关系,它按顺序运行" A" - > " Service OnDestroy" - >" B" - >" C&#34 ;, 我不知道为什么成功的方式,我不知道方式是否好方法!

  3. 结果

    11-13 10:04:32.137 27947-27947 / info.dodata.screenrecorder E / My:A

    11-13 10:04:32.147 27947-27947 / info.dodata.screenrecorder E / My:B

    11-13 10:04:32.157 27947-27947 / info.dodata.screenrecorder E / My:C

    11-13 10:04:32.157 27947-27947 / info.dodata.screenrecorder E / My:Service OnDestroy

    UIAbou.cs

    public class UIAbout extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.layout_about);
    
            Intent intent1 = new Intent(UIAbout.this,bll.RecordService.class);
            startService(intent1);
    
            Button btnReturn = (Button) findViewById(R.id.btnReturn);
            btnReturn.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.e("My", "A");
    
                    Intent intent1 = new Intent(UIAbout.this,bll.RecordService.class);
                    stopService(intent1);
    
                    Log.e("My", "B");
    
                    Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_LONG).show();
    
                    Log.e("My", "C");
                }
            });
    
        }
    
    }
    

    RecordService.cs

    public class RecordService extends Service {
    
        private Context mContext;
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public void onCreate(){
    
        }
    
        @Override
        public void onDestroy(){
            Log.e("My","Service OnDestroy");
            super.onDestroy(); //It seems that the APP is OK if I remove this.
        }
    
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
             return super.onStartCommand(intent,flags,startId);
        }
    
    
    }
    

    =======================我的方式1 ================== ====================

    我设置了一个标记isServiceStoped来监控Stop Service是否已经完成,但我的应用程序在显示结果后挂断了" 11-13 11:31:23.107 7599-7599 / info.dodata.screenrecorder E / My :A"

    新UIAbout.cs

    public class UIAbout extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.layout_about);
    
            Intent intent1 = new Intent(UIAbout.this,bll.RecordService.class);
            startService(intent1);
    
            Button btnReturn = (Button) findViewById(R.id.btnReturn);
            btnReturn.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.e("My", "A");
    
                    Intent intent1 = new Intent(UIAbout.this, bll.RecordService.class);
                    stopService(intent1);
    
                    while (RecordService.isServiceStoped==false){
                        //It block 
                    }
    
                    Log.e("My", "B");
    
                    Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_LONG).show();
    
                    Log.e("My", "C");
                }
            });
    
        }
    
    }
    

    新RecordService.cs

    public class RecordService extends Service {
    
       public static boolean isServiceStoped=true;
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO Auto-generated method stub
            return null;
        }
    
    
        @Override
        public void onCreate(){
    
        }
    
        @Override
        public void onDestroy(){
            Log.e("My", "Service OnDestroy");
            isServiceStoped=true;
            super.onDestroy(); //It seems that the APP is OK if I remove this.
        }
    
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
    
            isServiceStoped=false;
            return super.onStartCommand(intent,flags,startId);
        }
    
    
    }
    

    =====================我的方式2 ================= =========================

    我尝试将代码放入函数new Handler().postDelayed(new Runnable() {},它没关系,它按顺序运行" A" - > " Service OnDestroy" - >" B" - >" C",

    我不知道为什么成功的方式,我不知道方式是否好方法

    最后一个UIAbout.cs

    public class UIAbout extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.layout_about);
    
            Intent intent1 = new Intent(UIAbout.this,bll.RecordService.class);
            startService(intent1);
    
            Button btnReturn = (Button) findViewById(R.id.btnReturn);
            btnReturn.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.e("My", "A");
    
                    Intent intent1 = new Intent(UIAbout.this, bll.RecordService.class);
                    stopService(intent1);
    
                    new Handler().postDelayed(new Runnable() {
                        public void run() {
                            Log.e("My", "B");
    
                            Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_LONG).show();
    
                            Log.e("My", "C");
                        }
                    }, 1);
    
    
                }
            });
    
        }
    
    }
    

    最后一次RecordService.cs

    public class RecordService extends Service {
    
        private Context mContext;
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public void onCreate(){
    
        }
    
        @Override
        public void onDestroy(){
            Log.e("My", "Service OnDestroy");
            super.onDestroy(); //It seems that the APP is OK if I remove this.
        }
    
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            return super.onStartCommand(intent,flags,startId);
        }
    }
    

3 个答案:

答案 0 :(得分:1)

  1. 不,您无法同步停止服务。 stopService()是停止服务的请求。它会在一段时间后尽快停止。

  2. 不,您无法从onDestroy()方法中删除super.onDestroy()并仍然可以正常工作。

答案 1 :(得分:1)

  1. 您无法控制完全停止正在运行的服务的时间。使用stopService(),其余的都不在您的手中。您可以使用处理程序来监视服务在移动到B之前已停止,但我不确定您为什么要这样做。不是一个好习惯。
  2. 是的,你可以删除onDestroy中的super.onDestroy(),但我不建议你这样做。您的应用可能会运行,但会留下不需要的资源。 这里onDestroy()在android SDK中的样子如何:

    @CallSuper
    protected void onDestroy() {
        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onDestroy " + this);
        mCalled = true;
    
        // dismiss any dialogs we are managing.
        if (mManagedDialogs != null) {
            final int numDialogs = mManagedDialogs.size();
            for (int i = 0; i < numDialogs; i++) {
                final ManagedDialog md = mManagedDialogs.valueAt(i);
                if (md.mDialog.isShowing()) {
                    md.mDialog.dismiss();
                }
            }
            mManagedDialogs = null;
        }
    
        // close any cursors we are managing.
        synchronized (mManagedCursors) {
            int numCursors = mManagedCursors.size();
            for (int i = 0; i < numCursors; i++) {
                ManagedCursor c = mManagedCursors.get(i);
                if (c != null) {
                    c.mCursor.close();
                }
            }
            mManagedCursors.clear();
        }
    
        // Close any open search dialog
        if (mSearchManager != null) {
            mSearchManager.stopSearch();
        }
    
        getApplication().dispatchActivityDestroyed(this);
    }
    
  3. *示例* 可能存在一些编译错误,但您会明白这一点。

    public class UIAbout extends Activity {
    private Handler mHandler = new Handler();
    private Runnable checkServiceHandler;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.layout_about);
            Intent intent1 = new Intent(UIAbout.this,bll.RecordService.class);
            startService(intent1);
            Button btnReturn = (Button) findViewById(R.id.btnReturn);
            btnReturn.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.e("My", "A");
                    Intent intent1 = new Intent(UIAbout.this, bll.RecordService.class);
                    stopService(intent1);
                    checkServiceHandler = new Runnable() {
                   public void run() {
                      if(RecordService.isServiceStoped){
                           mHandler.removeCallbacks(checkServiceHandler );
                           somemethod();
                      } else{
                            mHandler.postDelayed(checkServiceHandler, 500);
                       }
                     }
                   };
                  mHandler.postDelayed(checkServiceHandler, 500);            }
            });
        }
      private void somemethod(){
                    Log.e("My", "B");
                    Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_LONG).show();
                    Log.e("My", "C");  
      }
    }
    

答案 2 :(得分:1)

您应该以一种在您的服务被销毁时无关心的方式实施您的代码。

反正。如果您确实需要确切的时刻,可以使用Android的广播系统从您的服务中激发意图。

在您的服务中:

@Override
public void onDestroy()
{
    super.onDestroy();
    LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(CONST_SERVICE_DESTROYED));
}

在您的活动中:

private BroadcastReceiver receiver = new BroadcastReceiver()
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        // your B here

        // your C here
    }
};

您需要注册和取消注册您的接收器:

@Override
protected void onResume()
{
    super.onResume();
    LocalBroadcastManager.getInstance(this).registerReceiver(receiver, new IntentFilter(CONST_SERVICE_DESTROYED));
}

@Override
protected void onPause()
{
    super.onPause();
    LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
}

可以找到Android广播系统的一个很好的解释和示例here