Android 安卓:从我的应用程序切换后,系统变得无响应
我正在编写一个时钟应用程序,它使用一些动画逻辑。在onCreate()中,我的应用程序活动分配一个类的实例,该类扩展了在run()中循环执行逻辑处理的线程。我正在使用一个线程化的SurfaceView(根据LunarLander示例,但带有上下文修复开关)来管理画布的绘图 只要有焦点,应用程序就可以正常运行。我在onPause()中挂起()逻辑线程,在onResume()中恢复()逻辑线程,并在onDestroy()中停止()逻辑线程,以确保用户切换时它不会消耗资源 此应用程序在模拟器上运行时不会出现问题。我可以随时切换回应用程序,不会产生任何不良影响 但是,当在物理硬件上运行Android系统时,如果你离开我的应用程序并返回几次,整个系统就会失去响应。最终,手机会忽略所有输入,包括顶部的睡眠/电源开关,必须通过卸下电池重新启动 作为测试,我禁用了逻辑线程的创建,但让渲染代码保持不变,并运行了一点动画逻辑,它解决了问题,所以我觉得我正在使用这个逻辑处理线程做的事情对系统来说一定非常糟糕。我是新手,所以我可能犯了个错误 任何关于我如何可能剖析这个问题的帮助或信息的指点都是非常感谢的 编辑:列出活动源。我已经取出了少量与线程无关的原油,希望能够澄清清单。(对不起,如果我弄乱了格式,这里是新的)Android 安卓:从我的应用程序切换后,系统变得无响应,android,Android,我正在编写一个时钟应用程序,它使用一些动画逻辑。在onCreate()中,我的应用程序活动分配一个类的实例,该类扩展了在run()中循环执行逻辑处理的线程。我正在使用一个线程化的SurfaceView(根据LunarLander示例,但带有上下文修复开关)来管理画布的绘图 只要有焦点,应用程序就可以正常运行。我在onPause()中挂起()逻辑线程,在onResume()中恢复()逻辑线程,并在onDestroy()中停止()逻辑线程,以确保用户切换时它不会消耗资源 此应用程序在模拟器上运行时不
公共类活动扩展活动
实现SensorEventListener
{
//----选项(共享首选项)----
//剪,两个布尔人
// --------------------------------------------------------
私有void LoadPreferences()
{
}//结束EyesClockActivity.LoadPreferences()
// --------------------------------------------------------
私有void SavePreferences()
{
}//结束EyesClockActivity.SavePreferences()
// ========================================================
私有类EyesClockActivityThread扩展线程
{
私有长m_LastUpdateMilliSeconds;
私有布尔m_running=false;
公共void SetRunning(最终布尔运行)
{
//如果重新启动,不希望出现巨大的时间飞跃
if((m_running==false)
&&(正在运行==true))
{
m_LastUpdateMilliSeconds=System.currentTimeMillis();
}
m_running=running;
}
// ----------------------------------------------
公共活动线程()
{
m_位=新眼位[4];
整数指数;
对于(索引=0;索引更新之间的毫秒)
{
int minute=Calendar.getInstance().get(Calendar.minute);
//除非分钟改变了,否则不要费心设置时间
如果((分钟%10)!=m_位数[0]。GetCurrentDigit()
{
int hour=Calendar.getInstance().get(Calendar.hour\u OF\u DAY);
设定时间(小时、分钟);
}
float secondsSinceLastUpdate=(float)((currentTime毫秒-m_LastUpdateMilliSeconds)/1000.0);
用于(眼位数:m_位数)
{
数字更新(secondsSinceLastUpdate);
}
//全局更新例程
m_LastUpdateMilliSeconds=System.currentTimeMillis();
}
}//如果m_正在运行,则结束
}
}//end-EyesClockActivityThread.run()
}//结束类EyesClockActivityThread
私有EyesClockActivityThread m_EyesActivityThread;
私人眼表视图m_眼表视图;
//----传感器接口----
私人SensorManager m_SensorManager;
专用传感器m_加速度计;
// -------------------------------------------------------------------------------
/**在首次创建活动时调用*/
@凌驾
创建时的公共void(Bundle savedInstanceState)
{
EyeDigit.InitDigitDescriptors();
m_EyesActivityThread=新的EyesClockActivityThread();
//没有标题栏
requestWindowFeature(窗口。功能\u无\u标题);
m_EyesActivityThread.SetRunning(true);
m_EyesActivityThread.start();
LoadPreferences();
苏佩
public class EyesClockActivity extends Activity
implements SensorEventListener
{
// ---- options (shared preferences) ----
// snip, couple of booleans
// --------------------------------------------------------
private void LoadPreferences()
{
} // end EyesClockActivity.LoadPreferences()
// --------------------------------------------------------
private void SavePreferences()
{
} // end EyesClockActivity.SavePreferences()
// ========================================================
private class EyesClockActivityThread extends Thread
{
private long m_LastUpdateMilliSeconds;
private boolean m_running = false;
public void SetRunning( final boolean running )
{
// if restarting, don't want huge time leap
if ( ( m_running == false )
&& ( running == true ) )
{
m_LastUpdateMilliSeconds = System.currentTimeMillis();
}
m_running = running;
}
// ----------------------------------------------
public EyesClockActivityThread()
{
m_digits = new EyeDigit[4];
int index;
for ( index = 0; index < m_digits.length; ++index )
{
m_digits[ index ] = new EyeDigit();
}
m_digits[0].SetCurrentDigit( 0 );
m_digits[1].SetCurrentDigit( 0 );
m_digits[2].SetCurrentDigit( 0 );
m_digits[3].SetCurrentDigit( 0 );
m_TestDigit.SetCurrentDigit( m_currentDigit );
m_LastUpdateMilliSeconds = System.currentTimeMillis();
m_lastDigitChangeMilliseconds = System.currentTimeMillis();
int minute = Calendar.getInstance().get(Calendar.MINUTE);
int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY );
SetTime( hour, minute );
} // end EyesClockActivityThread constructor
// --------------------------------------------------------------------
// sets digits to display specified hour,minute
private void SetTime( final int hour, final int minute )
{
} // end method EyesClockActivityThread.SetTime()
// ----------------------------------------------
public void run()
{
while (true)
{
if ( m_running )
{
final float updatesPerSecond = 30.0f;
final long milliSecondsBetweenUpdates = (long)(( 1.0f / updatesPerSecond ) * 1000.0f);
long currentTimeMilliSeconds = System.currentTimeMillis();
// TODO sleep here instead of checking constantly
if ( (currentTimeMilliSeconds - m_LastUpdateMilliSeconds) > milliSecondsBetweenUpdates )
{
int minute = Calendar.getInstance().get(Calendar.MINUTE);
// don't bother setting time unless minute has changed
if ( (minute % 10) != m_digits[0].GetCurrentDigit() )
{
int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY );
SetTime( hour, minute );
}
float secondsSinceLastUpdate = (float)((currentTimeMilliSeconds - m_LastUpdateMilliSeconds) / 1000.0);
for ( EyeDigit digit : m_digits )
{
digit.Update( secondsSinceLastUpdate );
}
// global update routines
m_LastUpdateMilliSeconds = System.currentTimeMillis();
}
} // end if m_running
}
} // end EyesClockActivityThread.run()
} // end class EyesClockActivityThread
private EyesClockActivityThread m_EyesActivityThread;
private EyesClockSurfaceView m_EyesSurfaceView;
// ---- sensor interface ----
private SensorManager m_SensorManager;
private Sensor m_Accelerometer;
// -------------------------------------------------------------------------------
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
EyeDigit.InitDigitDescriptors();
m_EyesActivityThread = new EyesClockActivityThread();
// No Title bar
requestWindowFeature(Window.FEATURE_NO_TITLE);
m_EyesActivityThread.SetRunning(true);
m_EyesActivityThread.start();
LoadPreferences();
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
m_EyesSurfaceView = (EyesClockSurfaceView)findViewById(R.id.eyesclocksurfaceview);
Configuration config = getResources().getConfiguration();
m_EyesSurfaceView.SetOrientation( config.orientation );
m_EyesSurfaceView.SetDigits( m_EyesActivityThread.GetDigits() );
m_SensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
m_Accelerometer = m_SensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
} // end method EyesClockActivity.onCreate()
// ----------------------------------------------
protected void onPause()
{
super.onPause();
// pause activity thread
m_EyesActivityThread.SetRunning(false);
m_EyesActivityThread.suspend();
// quit sensor listening
m_SensorManager.unregisterListener(this);
} // end method EyesClockActivity.onPause()
// ----------------------------------------------------
protected void onResume()
{
super.onResume();
// resume activity thread
m_EyesActivityThread.SetRunning(true);
m_EyesActivityThread.resume();
m_SensorManager.registerListener(this, m_Accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
} // end method EyesClockActivity.onResume()
// ------------------------------------------------------
protected void onDestroy()
{
super.onDestroy();
m_EyesActivityThread.SetRunning(false);
m_EyesActivityThread.stop();
m_SensorManager.unregisterListener(this);
// quit sensor listening
m_SensorManager.unregisterListener(this);
} // end method EyesClockActivity.onDestroy()
// -------------------------------------------------------
public void onAccuracyChanged(Sensor sensor, int accuracy)
{
}
// ----------------------------------------------------
public void onSensorChanged(SensorEvent event)
{
if ( ( event.values[0] > 15.0f )
|| ( event.values[1] > 15.0f )
|| ( event.values[2] > 15.0f ) )
{
m_EyesActivityThread.StartGoogleyEvent();
}
} // end method EyesClockActivity.onSensorChanged()
// ---- options menu ----
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// add cursor blink toggle item
menu.add( Menu.NONE, R.id.toggle_blink, Menu.NONE, R.string.string_blink_cursor);
if ( GetTwelveHourDisplay())
{
menu.add( Menu.NONE, R.id.toggle_twelve_hour_display, Menu.NONE, R.string.string_24_hour_display );
}
else
{
menu.add( Menu.NONE, R.id.toggle_twelve_hour_display, Menu.NONE, R.string.string_12_hour_display );
}
return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu)
{
super.onPrepareOptionsMenu(menu);
MenuItem displayItem = menu.getItem(1);
if ( displayItem != null )
{
if ( GetTwelveHourDisplay())
{
displayItem.setTitle(R.string.string_24_hour_display);
}
else
{
displayItem.setTitle(R.string.string_12_hour_display);
}
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle item selection
switch (item.getItemId())
{
case R.id.toggle_twelve_hour_display:
ToggleTwelveHourDisplay();
int minute = Calendar.getInstance().get(Calendar.MINUTE);
int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY );
m_EyesActivityThread.SetTime( hour, minute );
SavePreferences();
return true;
case R.id.toggle_blink :
ToggleBlinkCursor();
SavePreferences();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}