流媒体在线广播,在主线程上工作太多

时间:2014-06-06 09:47:04

标签: java android multithreading android-mediaplayer audio-streaming

the issue

我正在尝试使用播放和暂停按钮在简单的应用中实现在线广播流。我在onCreate()方法中唯一做的就是在单击按钮时启动和停止服务,当我启动服务时应用程序正在抛出一条消息,并且收音机开始缓冲说“该应用程序无法正常工作“,选项”关闭应用程序/等待“,并在logCat中,它说应用程序在它的主线程上做了太多工作。我无法理解为什么因为所有的辛苦工作都在服务中完成,而不是在onCreate()方法中。

我的主要活动:

public class MainActivity extends Activity {

    ImageButton startButton;
    static Context context;
    boolean isPlaying;
    boolean playPause = false;
    Intent streamService;
    SharedPreferences prefs;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = this;
        AudioManager audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        audio.adjustStreamVolume(AudioManager.STREAM_MUSIC,
                AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
        startButton = (ImageButton) findViewById(R.id.music_controls);
        prefs = PreferenceManager.getDefaultSharedPreferences(context);
        getPrefs();
        streamService = new Intent(MainActivity.this, StreamService.class);

        startButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                if (playPause) {
                    stopService(streamService);
                    startButton.setBackgroundDrawable(getResources().getDrawable(R.drawable.ic_play));
                    playPause = false;
                    Log.d("Radio:   ", "Stoping......");
                }else {
                    // TODO Auto-generated method stub

                    Log.d("Radio:   ", "Starting......");
                    startService(streamService);
                    startButton.setBackgroundDrawable(getResources().getDrawable(R.drawable.ic_pause));
                    playPause = true;
                }
            }
        });

    }

    public void onPrepared (MediaPlayer mp){

    }

    public void getPrefs() {
        isPlaying = prefs.getBoolean("isPlaying", false);
        if (isPlaying) playPause = false;
    }

}

我的服务:

public class StreamService extends Service {
    private static final String TAG = "StreamService";
    MediaPlayer mp;
    boolean isPlaying;
    SharedPreferences prefs;
    SharedPreferences.Editor editor;
    Notification n;
    NotificationManager notificationManager;
    // Change this int to some number specifically for this app
    int notifId = 5315;

    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @SuppressWarnings("deprecation")
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate");

        // Init the SharedPreferences and Editor
        prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        editor = prefs.edit();

        // Set up the buffering notification
        notificationManager = (NotificationManager) getApplicationContext()
                .getSystemService(NOTIFICATION_SERVICE);
        Context context = getApplicationContext();

        String notifTitle = context.getResources().getString(R.string.app_name);
        String notifMessage = context.getResources().getString(R.string.buffering);

        n = new Notification();
        n.icon = R.drawable.ic_launcher;
        n.tickerText = "A carregar...";
        n.when = System.currentTimeMillis();

        Intent nIntent = new Intent(context, MainActivity.class);
        PendingIntent pIntent = PendingIntent.getActivity(context, 0, nIntent, 0);

        n.setLatestEventInfo(context, notifTitle, notifMessage, pIntent);

        notificationManager.notify(notifId, n);

        // It's very important that you put the IP/URL of your ShoutCast stream here
        // Otherwise you'll get Webcom Radio
        String url = "My stream url";
        mp = new MediaPlayer();
        mp.setAudioStreamType(AudioManager.STREAM_MUSIC);

        try {
            mp.setDataSource(url);
            mp.prepare();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            Log.e(TAG, "SecurityException");
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            Log.e(TAG, "IllegalStateException");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            Log.e(TAG, "IOException");
        }
    }

    public int onStartCommand(Intent intent,int flags, int startId) {
        mp.start();
        // Set the isPlaying preference to true
        editor.putBoolean("isPlaying", true);
        editor.commit();

        Context context = getApplicationContext();
        String notifTitle = context.getResources().getString(R.string.app_name);
        String notifMessage = context.getResources().getString(R.string.now_playing);

        n.icon = R.drawable.ic_launcher;
        n.tickerText = notifMessage;
        n.flags = Notification.FLAG_NO_CLEAR;
        n.when = System.currentTimeMillis();

        Intent nIntent = new Intent(context, MainActivity.class);
        PendingIntent pIntent = PendingIntent.getActivity(context, 0, nIntent, 0);

        n.setLatestEventInfo(context, notifTitle, notifMessage, pIntent);
        // Change 5315 to some nother number
        notificationManager.notify(notifId, n);

        return START_STICKY;
    }


    @Override
    public void onDestroy() {
        Log.d(TAG, "onDestroy");
        mp.stop();
        mp.release();
        mp = null;
        editor.putBoolean("isPlaying", false);
        editor.commit();
        notificationManager.cancel(notifId);
    }

}

1 个答案:

答案 0 :(得分:1)

正常服务在主线程上运行。请改用IntentService。阅读有关服务http://developer.android.com/reference/android/app/Service.html

的信息