我是Android开发的新手,我需要一些小问题的帮助。 我有一个后台服务,它运行我的媒体播放器并与我的PlayerActivity进行通信。 到目前为止一切都很好。
我需要安排不同时段的曲目执行。即播放曲目x一分钟而不是播放曲目y 30秒等。
所以我从PlayerActivity调用MyTimer线程,这个线程在特定时间抛出事件,
PlayerActivity捕获Event并调用MediaplayerService next()方法。
我的问题是,如果我调用next()而没有线程它工作正常,如果我用我得到的线程调用它
mContext is null, can't getMirrorDisplayStatus!!!
有媒体播放器警告(1,902) 我试图通过Handler.post()和runOnUiThread()从PlayerActivity运行此线程 我得到了同样的错误。
下面是MyTimer Thread的代码。
public class MyTimer implements Runnable {
private Object mPauseLock;
private boolean mPaused;
private boolean mFinished;
private TimeSection section;
public Trainer()
{
mPauseLock = new Object();
mPaused = false;
mFinished = false;
BusProvider.getInstance().register(this);
}
@Override
public void run()
{
while (!mFinished)
{
TimerManager tm = TimerManager.getInstace();
this.section = tm.getCurrentTimeSection();
if(this.section == null)
mFinished = true;
else
{
tm.inc();
// produce sectionChangeEvent event
BusProvider.getInstance().post(produceSectionEvent());
try
{
Thread.sleep((this.section.getTypeDuration() * 1000));
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
synchronized (mPauseLock)
{
while (mPaused)
{
try
{
mPauseLock.wait();
} catch (InterruptedException e)
{
}
}
}
}
}
/**
* Call this on pause.
*/
public void onPause() {
synchronized (mPauseLock) {
mPaused = true;
}
}
/**
* Call this on resume.
*/
public void onResume() {
synchronized (mPauseLock) {
mPaused = false;
mPauseLock.notifyAll();
}
}
@Produce public TimeSectionEvent produceSectionEvent(){
return new TimeSectionEvent(this.section);
}
}
玩家活动的一些代码:
public class PlayerActivity implements
IMediaPlayerServiceClient{
private MediaPlayerService mService;
....
/**
* Binds to the instance of MediaPlayerService. If no instance of
* MediaPlayerService exists, it first starts a new instance of the service.
*/
public void bindToService()
{
Intent intent = new Intent(this, MediaPlayerService.class);
if (MediaPlayerServiceRunning())
{
// Bind to LocalService
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
} else
{
startService(intent);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
}
.....
/*
* This is how I start the timing thread
*/
private void startTiming()
{
mTimer = new MyTimer();
runOnUiThread(mTimer);
// trainingHandler.post(mTrainer);
}
public void next(TimeSection section)
{
mService.next(section);
}
/*
* Here I catch the TimeSectionEvent from MyTimer thread
*/
@Subscribe public void onSectionChanged(TimeSectionEvent e)
{
TimeSection section = e.getSection();
if(section != null)
next(section);
}
答案 0 :(得分:0)
每个活动都有上下文,所以我认为它与MediaPlayerService的上下文存在问题。
您正在使用bindService(...)将意图绑定到应绑定上下文的MediaPlayerService。
尝试检查当您尝试执行时绑定是否仍然存在" mService.next(section);"
答案 1 :(得分:0)
问题解决了!
问题在于我是时间线程在UI线程上运行 - >调用Thread.sleep
也使UI线程处于休眠状态。
所以我最终使用IntentService
在后台执行计时器线程作业。
public class TimingService extends IntentService{
private Object mPauseLock;
private boolean mPaused;
private boolean mFinished;
private TimeSection section;
public TimingService()
{
super("TimingService");
mPauseLock = new Object();
mPaused = false;
mFinished = false;
BusProvider.getInstance().register(this);
}
@Override
protected void onHandleIntent(Intent intent)
{
while (!mFinished)
{
TimerManager tm = TimerManager.getInstace();
this.section = tm.getCurrentTimeSection();
if(this.section == null)
mFinished = true;
else
{
tm.inc();
// produce sectionChangeEvent event
BusProvider.getInstance().post(produceSectionEvent());
try
{
Thread.sleep((this.section.getTypeDuration() * 1000));
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
synchronized (mPauseLock)
{
while (mPaused)
{
try
{
mPauseLock.wait();
} catch (InterruptedException e)
{
}
}
}
}
}
/**
* Call this on pause.
*/
public void onPause() {
synchronized (mPauseLock) {
mPaused = true;
}
}
/**
* Call this on resume.
*/
public void onResume() {
synchronized (mPauseLock) {
mPaused = false;
mPauseLock.notifyAll();
}
}
@Produce public TimeSectionEvent produceSectionEvent(){
return new TimeSectionEvent(this.section);
}
@Subscribe
public void onPauseEvent(PauseEvent e)
{
this.onPause();
}
@Subscribe
public void onResumeEvent(ResumeEvent e)
{
this.onResume();
}
}