gpt4 book ai didi

android - 应用程序在第二次运行时崩溃

转载 作者:行者123 更新时间:2023-11-30 04:12:59 25 4
gpt4 key购买 nike

我正在开发一款 Android 应用,我想每 30 秒更新一次背景。

我使用了一个计时器,它起作用了,但只有一次!应用程序第二次崩溃。

public Timer mTimer = null;    

public void loadColor()
{
setContentView(R.layout.color);

cur_scr = (LinearLayout) findViewById(R.id.colorScreen);
}

public void onClick(View v) throws InterruptedException
{
int id = v.getId();

switch (id)
{
case R.id.nextColor:
loadColor();

mTimer = new Timer();

mTimer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
Random gen = new Random();
cur_scr.setBackgroundColor(Color.argb(255, gen.nextInt(256), gen.nextInt(256), gen.nextInt(256)));
}
}, 0, 2000);

break;
}
}

洛卡特:

05-10 15:46:12.325: W/dalvikvm(346): threadid=9: thread exiting with uncaught exception (group=0x40015560)
05-10 15:46:12.344: E/AndroidRuntime(346): FATAL EXCEPTION: Timer-0
05-10 15:46:12.344: E/AndroidRuntime(346): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
05-10 15:46:12.344: E/AndroidRuntime(346): at android.view.ViewRoot.checkThread(ViewRoot.java:2932)
05-10 15:46:12.344: E/AndroidRuntime(346): at android.view.ViewRoot.invalidateChild(ViewRoot.java:642)
05-10 15:46:12.344: E/AndroidRuntime(346): at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:668)
05-10 15:46:12.344: E/AndroidRuntime(346): at android.view.ViewGroup.invalidateChild(ViewGroup.java:2511)
05-10 15:46:12.344: E/AndroidRuntime(346): at android.view.View.invalidate(View.java:5279)
05-10 15:46:12.344: E/AndroidRuntime(346): at android.view.View.setBackgroundDrawable(View.java:7626)
05-10 15:46:12.344: E/AndroidRuntime(346): at android.view.View.setBackgroundColor(View.java:7516)
05-10 15:46:12.344: E/AndroidRuntime(346): at com.haxad0x.tools.Core$1.run(Core.java:162)
05-10 15:46:12.344: E/AndroidRuntime(346): at java.util.Timer$TimerImpl.run(Timer.java:284)
05-10 15:46:14.194: D/AndroidRuntime(346): Shutting down VM
05-10 15:46:14.194: W/dalvikvm(346): threadid=1: thread exiting with uncaught exception (group=0x40015560)
05-10 15:46:14.194: I/Process(346): Sending signal. PID: 346 SIG: 9

请帮帮我!谢谢大家!


        case R.id.nextColor:
loadColor();

mTimer = new Timer();

mTimer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
runOnUiThread(new Runnable()
{
public void run() {
Random gen = new Random();
cur_scr.setBackgroundColor(Color.argb(255, gen.nextInt(256), gen.nextInt(256), gen.nextInt(256)));
}
});
}
}, 0, 2000);

break;

代码是这样工作的。我对此只有一个问题:它是一个长代码吗?我是说;它会因为所有空隙而影响性能吗?我可以缩短它吗?

最佳答案

很可能你的计时器在你的 Activity 被销毁后仍然存在,你的 View 不再存在(导致 findViewById 失败),并且你有一个不同的 View 可见。

您需要做的是停止 Activity 的 onDestroy 中的计时器。

将您的计时器变量创建为类级变量,也许是 mTimer..所以你会有

public class YourActivity extends Activity {
private Timer mTimer = null;

public void onCreate(Bundle state) {
//setContentView
mTimer = new Timer();
mTimer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
Random gen = new Random();
cur_scr = (LinearLayout) findViewById(R.id.colorScreen);
cur_scr.setBackgroundColor(Color.argb(255, gen.nextInt(256), gen.nextInt(256), gen.nextInt(256)));
}
}, 0, 30000);
}

public void onDestroy() {
mTimer.cancel();
}
}

-- 更新--虽然我仍然同意您应该进行上述更改,但看起来 TimerTask 是在新线程(而不是主 UI 线程)中运行的。您需要在 UI 线程上运行与 UI 一起工作的任何代码。使用 Activity.runOnUiThread像这样:

mTimer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
Random gen = new Random();
runOnUiThread(new Runnable() {
@Override
public void run() {
//actually you should probably put a try catch around the code below so it doesn't crash your app if somehow the view isn't found any longer.. It should work as long as you remove the timer task on onDestroy but to be safe i would put a try catch in.
cur_scr = (LinearLayout) findViewById(R.id.colorScreen);
cur_scr.setBackgroundColor(Color.argb(255, gen.nextInt(256), gen.nextInt(256), gen.nextInt(256)));
}
});

}
}

还有另一种使用处理程序可能更容易做到这一点的方法。

我会这样做:

public class YourActivity extends Activity {
private static final int BG_CHANGE_INTERVAL = 30 * 1000;
private Handler mHandler = null;
private Runnable mUpdateBgRunnable = new Runnable() {
Random gen = new Random();
@Override
public void run() {
cur_scr = (LinearLayout) findViewById(R.id.colorScreen);
cur_scr.setBackgroundColor(Color.argb(255, gen.nextInt(256), gen.nextInt(256), gen.nextInt(256)));
updateBg();
}

}
public void onCreate(Bundle state) {
//setContentView
mHandler = new Handler();
updateBg();
}

private void updateBg() {
mHandler.removeCallbacks(mUpdateBgRunnable);
mHandler.postDelayed(mUpdateBgRunnable, BG_CHANGE_INTERVAL);
}

public void onDestroy() {
mTimer.cancel();
}
}

查看此 article有关处理程序与计时器的更多信息。

关于android - 应用程序在第二次运行时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10524455/

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