Я создал IntentService
с бесконечным циклом внутри onHandleIntent
, затем добавил статические методы start, resume, pause, stop, чтобы напрямую вызывать его в моей деятельности.
Сценарий заключается в том, что внутри бесконечного цикла я вызываю методы обратного вызова, создающие новый поток для выполнения длинного процесса.
Проблема в том, что я беспокоюсь о непрерывном создании потоков из-за бесконечного цикла. Я уверен, что есть лучший способ справиться с этим. Я имею в виду ThreadPool или что-то, позволяющее использовать только один поток последовательно. Так что я экономлю время, память, накладные расходы и т.д ..
ДРУГОЙ ПОДХОД ОЧЕНЬ ДОБРО ПОЖАЛОВАТЬ. Спросите меня другую информацию по мере необходимости. Тогда я буду обновлять здесь.
Вот мои коды (посмотрите на SampleCallback):
IntentService
import android.app.IntentService;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
public class SampleCallbackIntentService extends IntentService {
private final String LOG_LOGCAT_TAG = "SampleCallbackIntentService";
private Handler _handler;
public SampleCallbackIntentService(String name) {
super(name);
}
@Override
public void onCreate() {
super.onCreate();
// initialize variables for pause & resume thread
_mPauseLock = new Object();
_mPaused = false;
_mFinished = false;
// initialize handler to switch to UI/Main thread
_handler = new Handler()
{
@Override
public void handleMessage(final Message msg)
{
_callback.doSomethingFromUIThread(msg);
}
};
}
private final SampleCallback _callback = new SampleCallback() {
@Override
public void doSomethingFromCurrentThread(final Object object) {
new Thread(new Runnable() {
@Override
public void run() {
//do long running process.
// I will access object here.
}
}).start();
}
@Override
public void doSomethingFromUIThread(final Message msg) {
//may update UI here.
}
};
private final int CALLBACK_MESSAGE = 1;
@Override
protected void onHandleIntent(Intent arg0) {
Log.i(LOG_LOGCAT_TAG, "loop started");
while (!_mFinished) {
// do stuff here
// create the object variable. Then pass to callback method
_callback.doSomethingFromCurrentThread(object);
// process and create the result to pass
String someResult = "some result here";
_handler.sendMessage(_handler.obtainMessage(CALLBACK_MESSAGE, someResult));
synchronized (_mPauseLock) {
while (_mPaused) {
try {
Log.i(LOG_LOGCAT_TAG, "loop paused");
_mPauseLock.wait();
Log.i(LOG_LOGCAT_TAG, "loop resumed");
} catch (InterruptedException e) {
Log.e(LOG_LOGCAT_TAG, "error occured on pause", e);
}
}
}
try {
//using sleep here might be not good design.
Thread.sleep(1000);
} catch (InterruptedException e) {
Log.e(LOG_LOGCAT_TAG, "error occured on sleep", e);
}
}
Log.i(LOG_LOGCAT_TAG, "loop ended");
}
private static Object _mPauseLock;
private static boolean _mPaused;
private static boolean _mFinished;
public static void start(Context context) {
Intent service = new Intent(context, SampleCallbackIntentService .class);
if(context.startService(service)==null) {
Log.e(LOG_LOGCAT_TAG, "Service cannot be started");
} else {
Log.i(LOG_LOGCAT_TAG, "start() called");
}
}
/**
* Call this on pause.
*/
public static void pause() {
Log.i(LOG_LOGCAT_TAG, "pause() called");
synchronized (_mPauseLock) {
_mPaused = true;
}
}
/**
* Call this on resume.
*/
public static void resume() {
Log.i(LOG_LOGCAT_TAG, "resume() called");
synchronized (_mPauseLock) {
_mPaused = false;
_mPauseLock.notifyAll();
}
}
public static void stop() {
if(_mPauseLock == null) return;
synchronized (_mPauseLock) {
Log.i(LOG_LOGCAT_TAG, "stop() called");
_mFinished = true;
}
}
}
SampleCallback
import android.os.Message;
public interface SampleCallback {
public void doSomethingFromCurrentThread(final Object object);
public void doSomethingFromUIThread(final Message msg);
}
UPDATES1
Я использую местоположение API помимо Google API. Я создам проект библиотеки Android и использую этот API, чтобы получить последнее местоположение (например, каждые 2 сек) в фоновом режиме.
На стороне приложения просто нужно вызвать статические методы, чтобы использовать его (например, start (context, callback), pause (), resume (), stop ()). Он имеет обратные вызовы для получения местоположения. После получения необходимой информации из объекта местоположения я создам новый поток для вызова моих собственных созданных обратных вызовов (которые реализованы на стороне приложения).