如何阻止任何活动在服务上运行的线程?

时间:2016-04-05 13:21:04

标签: android multithreading service handler

我有一个在主UI线程上运行的服务,我开始一个新的线程,每30秒重复一次方法。我一直试图在onpause()方法上停止其他活动的线程(当设备进入休眠状态时),但这不起作用。难道我做错了什么?有人可以帮忙吗?

我的重复任务线程

HandlerThread hThread = new HandlerThread("HandlerThread");
    hThread.start();

    final Handler handler = new Handler(hThread.getLooper());
    final long oneMinuteMs = 30 * 1000;

     Runnable eachMinute = new Runnable() {
        @Override
        public void run() {
            Intent service = new Intent(getApplicationContext(), AlarmIntentService.class);
            startService(service);
            handler.postDelayed(this, oneMinuteMs);

        }
    };// Schedule the first execution
    handler.postDelayed(eachMinute, oneMinuteMs);

here

2 个答案:

答案 0 :(得分:0)

为了阻止它,你需要在Handler上发送一个停止消息(你真的不需要更复杂的操作和类) 为此,请实现创建一个实际确定处理程序是否应该停止的方法,当它收到另一条消息时。

例如,实现一个名为AlarmManager的Singlethon类来处理重复任务

public class AlarmManager implements Handler.Callback {

private static final String TAG = AlarmManager.class.getName();

/**
 * The message "what" sent to the handler in order to stop
 */
private final int STOP_MESSAGE_ID = 0;

private static AlarmManager sInstance;

private Handler mHandler;

private Runnable mExecutionRunnable;

/**
 * Generates a single instance of this class
 */
public static AlarmManager getInstance() {
    if (sInstance == null) {
        sInstance = new AlarmManager();
    }
    return sInstance;
}

/**
 * Private constructor to avoid initializing this class by constructor.
 * {@link #getInstance()} should be used instead in order to assure that only one
 * instance of this class exists
 */
private AlarmManager() {
    mHandler = new Handler(this);
}

@Override
public boolean handleMessage(Message message) {
    switch (message.what) {
        case STOP_MESSAGE_ID:
            //Remove all stop messages
            mHandler.removeMessages(STOP_MESSAGE_ID);
            //Remove all callbacks
            mHandler.removeCallbacks(mExecutionRunnable);
            Log.d(TAG, "Stopping Operations");
            break;
        default:
            mHandler.handleMessage(message);
            break;
    }
    return false;
}

    /**
     * Schedule operations to start after a delay, and the operation will repeat after a period of time specified
     *
     * @param beforeStartDelay Delay in milliseconds before the first start
     * @param repeatTimeDelay Repeat delay in milliseconds between executions
     */
    public void scheduleExecutions(final long beforeStartDelay, final long repeatTimeDelay) {
    mExecutionRunnable = new Runnable() {
        @Override
        public void run() {
//                Intent service = new Intent(getApplicationContext(),     AlarmIntentService.class);
//                startService(service);
            Log.d(TAG, "Executing operation again");
            mHandler.postDelayed(this, repeatTimeDelay);
        }

    };
    mHandler.postDelayed(mExecutionRunnable,beforeStartDelay);

}

/**
 * Cancels the repeating executions
 */
public void stopExecution() {
    mHandler.sendEmptyMessage(STOP_MESSAGE_ID);
}

}

正如您所看到的,它处理带延迟的重复步骤,并在每次执行时打印一条Log消息(当前由方法参数设置),并在停止时打印日志。

为了控制此流程,请将其与您的Activity生命周期联系起来。

@Override
protected void onPause() {
    super.onPause();
    AlarmManager.getInstance().stopExecution();
}

@Override
protected void onResume() {
    super.onResume();
    AlarmManager.getInstance().scheduleExecutions(0,3000);
}

答案 1 :(得分:0)

我不知道这是不是最好的办法,但为什么不办理检查?

例如:

public class Generic {
private boolean isLooping = true;

...
    HandlerThread hThread = new HandlerThread("HandlerThread");
    hThread.start();

    final Handler handler = new Handler(hThread.getLooper());
    final long oneMinuteMs = 30 * 1000;

    Runnable eachMinute = new Runnable() {

        @Override
        public void run() {
            if(isLooping) {
                Intent service = new Intent(getApplicationContext(), AlarmIntentService.class);
                startService(service);
                handler.postDelayed(this, oneMinuteMs);
            }

        }
    };// Schedule the first execution
    handler.postDelayed(eachMinute, oneMinuteMs);

...

public void setLooping(boolean isLooping) {
    this.isLooping = isLooping;
}