gpt4 book ai didi

安卓 : system becomes unresponsive after switching away from my app

转载 作者:行者123 更新时间:2023-11-30 04:32:44 27 4
gpt4 key购买 nike

我正在编写一个使用一些动画逻辑的时钟应用程序。在 onCreate() 中,我的应用程序 Activity 分配了一个扩展 Thread 的类的实例,该类在 run() 中循环执行逻辑处理。我正在使用线程化的 SurfaceView(按照 LunarLander 示例,但使用上下文修复开关)来管理 Canvas 上的绘图。

只要有焦点,应用程序就可以正常运行。我在 onPause() 中挂起 () 逻辑线程,在 onResume() 中恢复 () 并在 onDestroy() 中停止 () 以确保当用户切换离开时它不会消耗资源。

此应用在模拟器上运行没有问题。我可以根据需要随时切换和返回该应用程序,而不会产生不良影响。

但是当在物理硬件上运行 Android 时,如果你从我的应用程序切换回来几次,整个系统将变得无响应。最终手机会忽略所有输入,包括顶部的 sleep /电源开关,并且必须通过取出电池重新启动。

作为测试,我禁用了逻辑线程的创建,但保留渲染代码并运行少量动画逻辑,它解决了问题,所以我觉得这是我正在做的事情对系统来说必须非常糟糕的逻辑处理线程。我是新手,所以我可能犯了一个菜鸟错误。

感谢任何帮助或指向有关我如何分析此问题的信息的指示。

编辑:列出 Activity 源。我删除了少量与线程无关的内容,希望能澄清列表。 (对不起,如果我弄乱了格式,这里是新的)

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

}

最佳答案

在 java 线程中,stop()resume()suspend() 已弃用,不应再使用。线程的自然顺序是让它在 onPause() 中死亡,并在 onResume()

中重新启动一个新线程

关于安卓 : system becomes unresponsive after switching away from my app,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7413991/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com