0
長期潛伏在這裏,我有一個問題。當處理SeekBar和滾動listview我的fps下降到零
我製作了一個頁面,顯示可用歌曲的列表(仍然在選擇選項中),它同時允許用戶啓動播客(最終將從服務器流式傳輸)並跳到下一個前一首歌曲通過按鈕。
然而,當播客開始播放時,seekbar/Textviews開始更新fps下降到大約1或2,編舞開始告訴我我跳幀(30和120之間,取決於我在做多少在後臺)。
我已經研究了線程和AsyncTasks,但我似乎無法弄清楚如何在我的系統中實現它們,所以我會保持一個體面的fps。有任何想法嗎?
我的主要活動的代碼如下:
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import com.example.globaldancechart.R;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.ListActivity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.TextView;
public class LijstScherm extends Activity {
public ImageView btnPrevious, btnPlay, btnNext;
public static SeekBar seek;
public TextView songNameBar;
public static TextView totaldurationtext, currentdurationtext;
public static int timechecker;
public static String async3 = "Updated";
int songcounter = 0;
int songplay = 0;
int songmax = 0;
int toplay = R.raw.summer;
AssetFileDescriptor afd;
public static final String[] songs = new String[] { "Comme Un Enfant",
"Burn", "Danger Zone", "Without You", "Young and Reckless",
"You Make Me Feel", "Atlas", "Antidote", "Beauty", "Event Horizon",
"Nasty Anthem", "Brutal" };
public static final String[] artists = new String[] { "Yelle", "SubVibe",
"Lana Del Rey", "KDrew", "Cobra Starship", "Balkansky",
"Swedish House Maffia", "Defeater", "Event Horizon",
"London Nebel", "Point.Blank" };
public static final long[] durations = new long[] { 0, 244000, 480000,
780000, 960000, 1140000, 1440000, 1680000, 1860000, 2040000,
2280000, 2640000 };
public static long[] async1 = new long[] { 1, 1, 1 };
Handler handler = new Handler();
static ListView listView;
public static List<ListUnit> listUnits;
final static MediaPlayer mp = new MediaPlayer();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.lijst_scherm);
Intent intent = new Intent(LijstScherm.this, Receiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
LijstScherm.this, 1, intent, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
if (calendar.get(Calendar.DAY_OF_WEEK) == java.util.Calendar.FRIDAY)
am.setRepeating(AlarmManager.RTC_WAKEUP, 82800000,
AlarmManager.INTERVAL_DAY * 7, pendingIntent);
btnPrevious = (ImageView) findViewById(R.id.btnPrevious);
btnPlay = (ImageView) findViewById(R.id.btnPlay);
btnNext = (ImageView) findViewById(R.id.btnNext);
seek = (SeekBar) findViewById(R.id.songProgress);
currentdurationtext = (TextView) findViewById(R.id.currentdurationtext);
totaldurationtext = (TextView) findViewById(R.id.totaldurationtext);
songNameBar = (TextView) findViewById(R.id.songNameBar);
afd = getApplicationContext().getResources().openRawResourceFd(
R.raw.mix);
try {
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
afd.getDeclaredLength());
} catch (IllegalArgumentException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalStateException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
final Runnable r = new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
if(mp.isPlaying()){
long currentPosition = mp.getCurrentPosition();
long totalDuration;
if ((currentPosition < durations[timechecker]) == true) {
if (durations[timechecker] > 0) {
totalDuration = durations[timechecker]
- durations[timechecker - 1];
currentPosition = currentPosition
- durations[timechecker - 1];
} else {
totalDuration = durations[timechecker];
}
} else {
LijstScherm.timechecker += 1;
totalDuration = durations[timechecker]
- durations[timechecker - 1];
currentPosition = currentPosition
- durations[timechecker -1];
}
currentdurationtext.setText(Utilities
.milliSecondsToTimer(currentPosition));
totaldurationtext
.setText(Utilities
.milliSecondsToTimer(totalDuration));
int progress = (int) (Utilities
.getProgressPercentage(
currentPosition,
totalDuration));
seek.setProgress(progress);
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
handler.post(this);
}};
mp.prepareAsync();
seek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
long tDuration, cDuration;
if (timechecker > 0) {
tDuration = durations[timechecker]
- durations[timechecker - 1];
cDuration = Utilities.progressToTimer(arg0.getProgress(),
tDuration);
} else {
tDuration = durations[timechecker + 1];
cDuration = Utilities.progressToTimer(arg0.getProgress(),
tDuration);
}
if (timechecker > 0)
mp.seekTo((int) (durations[timechecker - 1] + cDuration));
else
mp.seekTo((int) cDuration);
}
@Override
public void onStartTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
@Override
public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
// TODO Auto-generated method stub
}
});
btnPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mp.isPlaying() == false) {
mp.start();
btnPlay.setBackgroundResource(R.drawable.pause);
r.run();
} else {
mp.pause();
btnPlay.setBackgroundResource(R.drawable.play);
}
}
});
btnNext.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
timechecker += 1;
mp.seekTo((int) durations[timechecker]);
}
});
btnPrevious.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (timechecker > 0) {
if (mp.getCurrentPosition() < durations[timechecker - 1] + 2000) {
mp.seekTo((int) durations[timechecker - 1]);
} else {
timechecker -= 1;
mp.seekTo((int) durations[timechecker - 2]);
}
} else {
mp.seekTo(0);
}
}
});
listUnits = new ArrayList<ListUnit>();
for (int i = 0; i < songs.length - 1; i++) {
ListUnit item = new ListUnit(songs[i], artists[i], i + 1);
listUnits.add(item);
}
listView = (ListView) findViewById(R.id.gdclijst);
CustomListViewAdapter adapter = new CustomListViewAdapter(this,
R.layout.listunit, listUnits);
listView.setAdapter(adapter);
}
我ListViewAdapter的代碼如下:
import java.util.List;
import com.example.globaldancechart.R;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class CustomListViewAdapter extends ArrayAdapter<ListUnit> {
Context context;
public CustomListViewAdapter(Context context, int resourceId,
List<ListUnit> items) {
super(context, resourceId, items);
this.context = context;
}
/*private view holder class*/
private class ViewHolder {
TextView txtTitle;
TextView txtDesc;
ImageView arrow;
ImageView playbutton;
TextView play;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
ListUnit rowItem = getItem(position);
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.listunit, null);
holder = new ViewHolder();
holder.txtDesc = (TextView) convertView.findViewById(R.id.songname);
holder.txtDesc.setTag(position);
holder.playbutton = (ImageView) convertView.findViewById(R.id.playbutton);
holder.playbutton.setTag(position);
holder.txtTitle = (TextView) convertView.findViewById(R.id.artistname);
holder.txtTitle.setTag(position);
holder.arrow = (ImageView) convertView.findViewById(R.id.arrow);
holder.play = (TextView) convertView.findViewById(R.id.play);
holder.play.setText(String.valueOf(position + 1));
convertView.setTag(holder);
} else
holder = (ViewHolder) convertView.getTag();
holder.txtDesc.setText(rowItem.getArtist());
holder.txtTitle.setText(rowItem.getSong());
holder.arrow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RelativeLayout rl = (RelativeLayout) v.getParent();
TextView tv = (TextView) rl.findViewById(R.id.play);
int position = Integer.parseInt(tv.getText().toString());
Context c = getContext();
Intent i = new Intent(c, InfoScherm.class);
i.putExtra("position", position);
c.startActivity(i);
}
});
holder.playbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RelativeLayout rl = (RelativeLayout) v.getParent();
TextView tv = (TextView) rl.findViewById(R.id.play);
int position = Integer.parseInt(tv.getText().toString());
if(position > 0)
LijstScherm.timechecker = position - 1;
else
LijstScherm.timechecker = position;
}
});
return convertView;
}
}
我將在任何其他代碼,如果有必要
你期望什麼?你正在使用線程睡眠......更糟糕的是,你正在使用ui線程嗎? – Selvin 2015-01-20 22:38:01
這可能是問題,但後來我想知道,我如何確保SeekBar更新線程不是通過UI線程完成的?這可能會提高我的fps很多。 – AspiringJunior 2015-01-20 23:33:24
首先我沒有試圖理解你的代碼......但是'Thread.sleep'總是不好,m'key ...所以首先,擺脫它...然後嘗試使用'handler.postDeley'而不是' handler.post'與500 milis - 它應該像Thread.sleep一樣工作,但不會阻塞UI線程... – Selvin 2015-01-20 23:36:57