我有一个以1秒的间隔发出GPS请求的课程。
我还有一个Service
来保持通知存活。
此服务使用来自GPS的数据以1秒的间隔更新通知文本。
在应用程序中,我有一个BroadcastRecevier
,它监听服务更新并更改应用程序中的一些文本。
我得到了编舞问题(Choreographer(691): Skipped xxx frames! The application may be doing too much work on its main thread.
)
我在下面添加了我的代码,但从中删除了不必要的代码。 调试的挑战是通常需要30-90分钟才能发生错误,甚至不是每次都发生。
有什么建议吗?
import /*....*/;
public class SomeClass extends Service {
private static Context context;
private static Timer timer;
private static Handler handler = new Handler();
/* Notification begin */
private static Notification.Builder builder;
private static RemoteViews ongl;
private static Notification notification;
private static NotificationManager notificationManager;
private static int notifyID;
/* Notification end */
/* GPScalculator begin */
private static GpsCalculator gpsCalculator;
private static Boolean goalAchieved = false;
/* Sound notification */
private static MediaPlayer pl;
private static int kmCount;
/* Timer start*/
private static TimerTask timerTask;
/* Timer end*/
public static final String NOTIFICATION = "...";
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
context = this;
Bundle extras = intent.getExtras();
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent nintent = new Intent(this,MyClass.class);
nintent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
notifyID = 1;
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, nintent, 0);
builder = new Notification.Builder(context);
builder.setContentIntent(pendingIntent);
builder.setTicker("Run started");
builder.setSmallIcon(R.drawable.ic_launcher);
builder.setAutoCancel(false);
builder.setPriority(2);
builder.setOngoing(true);
ongl = new RemoteViews(NOTIFICATION, R.layout.ongoing_notification);
builder.setContent(ongl);
notification = builder.build();
startForeground(notifyID,notification);
pl = MediaPlayer.create(context, R.raw.applause6);
pl.start();
kmCount = 0;
gpsCalculator = new GpsCalculator(distanceToRun, runId);
Map<String, Object> mp = (Map<String, Object>) intent.getSerializableExtra("upr");
gpsCalculator.run(mp,this);
startRun();
return(START_NOT_STICKY);
}
public void startRun(){
timer = new Timer();
timerTask = new TimerTask() {
public void run() {
//use a handler to run a toast that shows the current timestamp
handler.post(new Runnable() {
public void run() {
Date dateNow = new Date();
String timeNow = String.valueOf(dateNow.getTime()/1000);
int timeLapsed = Integer.parseInt(timeNow) - Integer.parseInt(runId);
int hours = timeLapsed / 3600;
int minutes = (timeLapsed/60) % 60;
int seconds = timeLapsed % 60;
String hrs = String.valueOf(hours);
String mns = String.valueOf(minutes);
String scs = String.valueOf(seconds);
currentDistance = gpsCalculator.getTotalDistance();
/* Notify split */
int currentKm = currentDistance/1000;
if(currentKm > kmCount){
kmCount = currentKm;
pl.start();
}
Map<String, Object> map = new HashMap<String, Object>();
map.put("hrs",hrs);
map.put("mns",mns);
map.put("scs",scs);
map.put("distance",String.valueOf(currentDistance));
Intent intent1 = new Intent(NOTIFICATION);
if(distanceToRun<currentDistance){
if(!goalAchieved){
pl = MediaPlayer.create(context, R.raw.cheer2);
pl.start();
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
pl = MediaPlayer.create(context, R.raw.applause6);
}
},
4000);
goalAchieved = true;
ongl.setTextColor(R.id.ong_dist_txt, Color.parseColor("#FF1414"));
intent1.putExtra("finishedRun", true);
runResults = gpsCalculator.getRunResults();
}
}
intent1.putExtra("runProgress", (java.io.Serializable) map);
sendBroadcast(intent1);
ongl.setTextViewText(R.id.ong_time_txt,hrs+":"+mns+":"+scs);
notificationManager.notify(notifyID, notification);
}
});
}
};
timer.schedule(timerTask, 0, 1000);
}
@Override
public IBinder onBind(Intent intent) {
return(null);
}
public static void stopRun() {
if (timer != null) {
timer.cancel();
timer = null;
}
if(gpsCalculator != null){
gpsCalculator.stop();
}
}
public static Map<String, Object> getRunResults() {
return runResults;
}
public static String getRunId(){
return runId;
}
}