这是我的任务: 我需要运行2个后台服务。通过ksoap.another服务将我的移动数据同步到服务器我需要将我的gps位置发送到服务器。 所以我写了这个代码。但是当我添加gpsTimer部分时,它在加载application.please时给出了以下错误帮助我理清这个问题。或者告诉我任何其他方式来实现这个案例。
这是我的代码
public class BackgroundService extends Service {
private Timer timer;
private Timer gpsTimer;
public IBinder onBind(Intent intent) {return null;}
public void onCreate() {
super.onCreate();
timer = new Timer("BackgroundServiceTimer");
timer.schedule(syncTask, 1000L, 60 * 1000L);
gpsTimer = new Timer("GPSServiceTimer");
gpsTimer.schedule(syncTaskGps, 1000L, 10 * 1000L);
}
public void onDestroy() {
super.onDestroy();
timer.cancel();
timer = null;
gpsTimer.cancel();
gpsTimer = null;
}
public void onLowMemory() {
super.onLowMemory();
stopService(new Intent(com.lk.lankabell.android.activity.BackgroundService.class.getName()));
}
private TimerTask syncTaskGps = new TimerTask() {
public void run() {
Log.w("GPS Tracker", "Tracker going to run"+new Date());
LocationManager mlocManager =(LocationManager)getSystemService(Context.LOCATION_SERVICE);
LocationListener mlocListener = new MyLocationListener();
mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
}
};
private TimerTask syncTask = new TimerTask() {
public void run() {
if (isOnline() == true) {
Log.w("Method 2", "setUpdateCardAcceptTag");
setUpdateCardAcceptTag();
Log.w("Method 3", "getCardBulkSerialData");
getCardBulkSerialData();
Log.w("Method 12", "updateStockDataFromRemote");
updateStockDataFromRemote();
Log.w("Method 5", "SetRemarksData");
SetRemarksData();
Log.w("Method 6", "SetCardSaleData");
SetCardSaleData();
Log.w("Method 7", "synchMerchants");
synchMerchants();
Log.w("Method 9", "getUpdatedCities");
getUpdatedCities();
Log.w("Method 10", "getNotifications");
getNotifications();
Log.w("Method 11", "getNextSerialDetails");
getNextSerialDetails();
Log.w("Method 12", "getNextSerialDetails");
//synchLocations();
Log.w("Method 13", "synchLocations");
}
}
};
这是错误:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
答案 0 :(得分:2)
TimerTask在与UI线程不同的线程上运行,并且根据文档,如果调用线程没有Looper,则抛出RuntimeException
。尝试以这种方式更改代码:
private TimerTask syncTaskGps = new TimerTask() {
public void run() {
Looper.prepare();
Log.w("GPS Tracker", "Tracker going to run"+new Date());
LocationManager mlocManager =(LocationManager)getSystemService(Context.LOCATION_SERVICE);
LocationListener mlocListener = new MyLocationListener();
mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener, Looper.getMainLooper());
Looper.loop();
}
};
答案 1 :(得分:2)
使用Handler代替Timer / TimerTask
public class MyService extends Service {
private Handler mTimer = new Handler();
private Runnable mTask = new Runnable() {
@Override
public void run() {
//DO SOMETHING HERE
mTimer.postDelayed(this, interval*1000L);
}
};
private int interval = 60; // 60 seconds
public void onCreate() {
mTimer.postDelayed(mTask, interval*1000L); //start the timer for the first time
}
public void onDestroy() {
if(mTimer != null) {
mTimer.removeCallbacks(mTask); //cancel the timer
}
}
}
通过使用Handler,您可以随时重置间隔,例如,首先您希望它每5秒运行一次,而不是用户决定每1秒运行一次,只需更改间隔变量并调用mTimer.postDelayed试。