我正在开发一个Android应用程序,其中包括秒表。
秒表本身功能正常。它使用Runnable来更新UI并显示时间。
private Runnable updateTimerThread = new Runnable() {
public void run() {
timeInMilliseconds = SystemClock.uptimeMillis() - startTime;
updatedTime = timeSwapBuff + timeInMilliseconds;
int secs = (int) (updatedTime / 1000);
int mins = secs / 60;
secs = secs % 60;
int milliseconds = (int) (updatedTime % 1000);
if(mins > 99){
return;
}
mChronoMinutes.setText(mins + "");
mChronoSeconds.setText(String.format("%02d", secs));
mChronoMiliseconds.setText(String.format("%03d", milliseconds));
customHandler.postDelayed(this, 0);
}
};
但是我想包括一个计时器。我有一个按钮,当按下该按钮时,会将当前时间添加到我的列表中,并通知我的列表适配器。
按钮的onClickListener中有一些逻辑,但我认为这没什么大不了的。
这是onClickListener:
View.OnClickListener mLapListener = new View.OnClickListener() {
public void onClick(View v) {
lapCounter++;
int secs = (int) (updatedTime / 1000);
int mins = secs / 60;
secs = secs % 60;
int milliseconds = (int) (updatedTime % 1000);
//for laptime
int lapSecs = (int) ((updatedTime - lastLapTime) / 1000);
int lapMins = lapSecs / 60;
lapSecs = lapSecs % 60;
int lapMilliseconds = (int) ((updatedTime - lastLapTime) % 1000);
laps.add(0, "# " + lapCounter + " " + mins + " " + String.format("%02d", secs) + "," + String.format("%03d", milliseconds)
+ " " + lapMins + " " + String.format("%02d", lapSecs) + "," + String.format("%03d", lapMilliseconds));
adapter.notifyDataSetChanged();
lapListView.post(new Runnable() {
@Override
public void run() {
lapListView.smoothScrollToPosition(0);
}
});
lastLapTime = updatedTime;
}
};
如您所见,它获取当前时间和上一圈以来的时间,并将其显示在列表视图中。
这可以按预期工作,但是问题是,每当我按下圈按钮时,秒表本身便开始冻结,在第一圈中它几乎是不可见的,但是每当我按下按钮时,冻结就会变得更加明显。 20圈后,秒表将悬挂半秒左右。
我认为也许我在UI线程上做的工作太多了,所以我尝试使用AsyncTask在doInBackground中执行逻辑并在onPostExecute方法中更新listView。
但是,这没有任何区别,计时器在经过几圈后仍然开始冻结。
我是一个相当新的Android程序员,我真的不知道该怎么做或实际上是什么问题。
我希望有人可以帮助我!
我发现了另一件事,如果我开始足够快地单击圈按钮,那么最终它将FC并给我一个“致命信号6(SIGABRT)”,谷歌告诉我这与多线程相关。
提前致谢,
尼尔斯
编辑:
这是我使用过的asynctask,但是并没有改变任何东西。
private class AddLapTask extends AsyncTask<Void, Void, Void>
{
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
lapCounter++;
secs = (int) (updatedTime / 1000);
mins = secs / 60;
secs = secs % 60;
milliseconds = (int) (updatedTime % 1000);
//for laptime
lapSecs = (int) ((updatedTime - lastLapTime) / 1000);
lapMins = lapSecs / 60;
lapSecs = lapSecs % 60;
lapMilliseconds = (int) ((updatedTime - lastLapTime) % 1000);
lastLapTime = updatedTime;
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
laps.add(0, "# " + lapCounter + " " + mins + " " + String.format("%02d", secs) + "," + String.format("%03d", milliseconds)
+ " " + lapMins + " " + String.format("%02d", lapSecs) + "," + String.format("%03d", lapMilliseconds));
adapter.notifyDataSetChanged();
lapListView.post(new Runnable() {
@Override
public void run() {
lapListView.smoothScrollToPosition(0);
}
});
}
}
和我的ListAdapter:
public class LapListAdapter extends BaseAdapter {
private Context context;
private ArrayList<String> laps;
private int mSelectedItem;
public LapListAdapter(Context context, ArrayList<String> laps) {
this.context = context;
this.laps = laps;
}
@Override
public int getCount() {
return laps.size();
}
@Override
public Object getItem(int position) {
return laps.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
public int getSelectedItem() {
return mSelectedItem;
}
public void setSelectedItem(int selectedItem) {
mSelectedItem = selectedItem;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder = new Holder();
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.lap_item, null);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
holder.lap_info = (TextView) convertView.findViewById(R.id.lap_info);
Typeface roboto;
roboto = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Bold.ttf");
holder.lap_info.setText(laps.get(position));
holder.lap_info.setTypeface(roboto);
return convertView;
}
class Holder {
TextView lap_info;
}
}
希望能帮助到你
最佳答案
我敢打赌,正是造成您问题的TypeFace.createFromAsset调用。尝试删除该行,看看会发生什么。
您应该能够在适配器的构造函数中创建该字体并将其重新用于getView()方法,而不是每次都在getView方法中重新创建它。