处理 SeekBar 并滚动列表视图时,我的 fps 降为零

When handling the SeekBar and scrolling the listview my fps drops to zero

长期潜伏在这里,我有一个问题。

我制作了一个显示可用歌曲列表的页面(仍在使用 select 选项),同时允许用户启动播客(最终将从服务器流式传输)和通过按钮跳到下一首和上一首歌曲。

然而,当播客开始播放并且 seekbar/Textviews 开始更新 fps 下降到大约 1 或 2 时,Choreographer 开始告诉我我正在跳帧(在 30 到 120 之间,取决于我跳帧的程度)我在后台做)。

我研究了线程和 AsyncTasks,但我似乎无法弄清楚如何在我的系统中实现它们,所以我会保持不错的 fps。有什么想法吗?

我的主要Activity代码如下:

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;
    }
}

如有必要,我会在任何其他代码中进行编辑

问题主要出在我对Thread.Sleep的使用上。我用 handler.postDelayed(r,500) 替换了它,效果非常好! :D