gpt4 book ai didi

java - Android 计时器在取消时崩溃

转载 作者:行者123 更新时间:2023-12-02 07:51:05 25 4
gpt4 key购买 nike

我有一个计时器正在运行,然后它会关闭并执行一些操作,并且计时器启动正常。

然后我想做的是单击一个按钮,然后创建一封电子邮件。一切正常,除了在计时器运行时单击按钮时,应用程序崩溃了。当点击按钮时尝试取消计时器时,也会导致应用程序崩溃。

如有任何帮助,我们将不胜感激。

这是代码 fragment :

public class myApplication extends Activity {
StringBuilder str;
Timer t;
Button mailbutton;

public void onCreate(Bundle savedInstanceState) {

final StringBuilder str = new StringBuilder(1000);
super.onCreate(savedInstanceState);


setContentView(R.layout.main);

addListenerOnButton();


TimerTask task = new TimerTask() {

@Override
public void run()
{
/// do stuff here
}
}

t = new Timer();
t.schedule(task,2000,2000);

}


public void addListenerOnButton() {

mailbutton = (Button) findViewById(R.id.emailbutton);

mailbutton.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {

t.cancel();

Intent i = new Intent(Intent.ACTION_SEND);
i.setType("text/plain");
i.putExtra(Intent.EXTRA_EMAIL , new String[]{"email@domain.com"});
i.putExtra(Intent.EXTRA_SUBJECT, "subject");
i.putExtra(Intent.EXTRA_TEXT , str.toString());
try {
startActivity(Intent.createChooser(i, "Send mail"));
} catch (android.content.ActivityNotFoundException ex) {
}
}
});
}
}

LogCat 输出:

04-19 09:13:11.143: W/dalvikvm(12613): threadid=1: thread exiting with uncaught exception (group=0x40c421f8)
04-19 09:13:11.148: E/AndroidRuntime(12613): FATAL EXCEPTION: main
04-19 09:13:11.148: E/AndroidRuntime(12613): java.lang.NullPointerException
04-19 09:13:11.148: E/AndroidRuntime(12613): at uk.co.application.applicationActivity$2.onClick(applicationActivity.java:94)
04-19 09:13:11.148: E/AndroidRuntime(12613): at android.view.View.performClick(View.java:3591)
04-19 09:13:11.148: E/AndroidRuntime(12613): at android.view.View$PerformClick.run(View.java:14263)
04-19 09:13:11.148: E/AndroidRuntime(12613): at android.os.Handler.handleCallback(Handler.java:605)
04-19 09:13:11.148: E/AndroidRuntime(12613): at android.os.Handler.dispatchMessage(Handler.java:92)
04-19 09:13:11.148: E/AndroidRuntime(12613): at android.os.Looper.loop(Looper.java:137)
04-19 09:13:11.148: E/AndroidRuntime(12613): at android.app.ActivityThread.main(ActivityThread.java:4507)
04-19 09:13:11.148: E/AndroidRuntime(12613): at java.lang.reflect.Method.invokeNative(Native Method)
04-19 09:13:11.148: E/AndroidRuntime(12613): at java.lang.reflect.Method.invoke(Method.java:511)
04-19 09:13:11.148: E/AndroidRuntime(12613): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
04-19 09:13:11.148: E/AndroidRuntime(12613): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
04-19 09:13:11.148: E/AndroidRuntime(12613): at dalvik.system.NativeStart.main(Native Method)

最佳答案

这个计时器的具体用途是什么?我无法想象你会用它来做什么,因为它每 2 秒不断重复运行一次。您可能遇到的一件事是 Android 的线程问题。该计时器任务运行在与 Android UI 使用的主线程不同的线程上。如果您正在接触 Android 小部件或其他实例变量,那么您最终会遇到线程安全问题,并且如果您尝试这样做,Android 通常会抛出异常。因此,这取决于您试图用该线程完成什么,以及什么可能比创建另一个这样的线程更好。通常,我们会使用 Handler 定期在主线程上运行任务,而不是使用这样的 Timer,因为它会引入线程问题。

更新:

您刚刚确认了您刚才描述的严重线程安全问题。我所说的线程安全是指两个线程有​​可能同时读/写同一内存位置。这是一个大问题。事实上,您自己承认,您的 StringBuilder 实例在计时器线程和按钮回调之间共享,这意味着您在读取该 StringBuilder 时肯定会遇到线程安全问题。

这样做你会遇到持续不可预测的问题,并且你的代码在用户操作时永远不会稳定。首先,没有理由从另一个线程读取 GPS,因为 LocationManager 会在 GPS 发生变化时定期调用您。只需在调用时将其附加到 StringBuilder 或 ArrayList 上即可。 GPS 回调在主线程上运行,因此读取该变量的按钮逻辑不可能在修改该变量的同时发生。

您需要从代码中删除该计时器,并使用主线程来完成所有工作。或者您必须同步对数据结构的访问。 Android 中发生的大多数回调都在主线程上运行。因此,如果您只是将记录历史值的逻辑移动到那里的数据结构中,而不是放在计时器中,那就没问题了。您可能必须将 GPS 与您尝试记录的其他内容分开记录,但您可以将它们格式化为按钮点击处理程序中的字符串。

您的 NPE 位于文件的第 94 行。如果不知道源代码的行号,我们无法帮助您。但是,当您遇到线程安全问题时,您会遇到这些类型的问题。它们会让你发疯,所以有必要了解我的警告,并了解有关线程和安全控制的更多信息。

关于java - Android 计时器在取消时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10219849/

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