我正在研究这个秒表应用程序,并且在运行我的应用程序时我一直关闭这个奇怪的力量。
当在模拟器上运行应用程序时,应用程序启动就好了,我可以看到布局和所有内容,通常可以启动秒表,停止并重置它,但是当我尝试再次启动时它通常会崩溃,有时候,我可以在崩溃之前多次启动,重置和启动秒表,还有一些时候我在第一次启动时崩溃
我是android开发的新手,所以任何帮助都会非常感激。谢谢你
这是我的Java文件:
package com.tutorial.stopwatch;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.view.Menu;
import android.app.Activity;
import android.content.res.Configuration;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.graphics.Typeface;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
private TextView tempTextView; //Temporary TextView
private Button tempBtn; //Temporary Button
private Handler mHandler = new Handler();
private long startTime;
private long elapsedTime;
private final int REFRESH_RATE = 100;
private String hours,minutes,seconds,milliseconds;
private long secs,mins,hrs,msecs;
private boolean stopped = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkScreenDensity();
/*-------Setting the TextView Fonts-----------*/
Typeface fonttimer = Typeface.createFromAsset(getAssets(), "roboto.ttf");
tempTextView = (TextView) findViewById(R.id.timer);
tempTextView.setTypeface(fonttimer);
tempTextView = (TextView) findViewById(R.id.timerMs);
tempTextView.setTypeface(fonttimer);
tempTextView = (TextView) findViewById(R.id.timerHs);
tempTextView.setTypeface(fonttimer);
Typeface font = Typeface.createFromAsset(getAssets(), "roboto.ttf");
tempTextView = (TextView) findViewById(R.id.backgroundText);
tempTextView.setTypeface(font);
Button tempBtn = (Button)findViewById(R.id.startButton);
tempBtn.setTypeface(font);
tempBtn = (Button)findViewById(R.id.resetButton);
tempBtn.setTypeface(font);
tempBtn = (Button)findViewById(R.id.stopButton);
tempBtn.setTypeface(font);
}
private void checkScreenDensity(){
tempTextView = (TextView)findViewById(R.id.backgroundText);
switch (getResources().getDisplayMetrics().densityDpi) {
case DisplayMetrics.DENSITY_LOW:
tempTextView.setVisibility(View.GONE);
break;
case DisplayMetrics.DENSITY_MEDIUM:
tempTextView.setVisibility(View.GONE);
break;
case DisplayMetrics.DENSITY_HIGH:
tempTextView.setVisibility(View.VISIBLE);
break;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
//---------- on click procedures - id from layout.xml -----------
public void startClick (View view){
showStopButton();
if(stopped){
startTime = System.currentTimeMillis() - elapsedTime;
}
else{
startTime = System.currentTimeMillis();
}
mHandler.removeCallbacks(startTimer);
mHandler.postDelayed(startTimer, 0);
}
public void stopClick (View view){
hideStopButton();
mHandler.removeCallbacks(startTimer);
stopped = true;
}
public void resetClick (View view){
stopped = false;
((TextView)findViewById(R.id.timer)).setText("00:00");
((TextView)findViewById(R.id.timerMs)).setText(":00");
((TextView)findViewById(R.id.timerHs)).setText("00:");
}
//---------- Button change (start/reset to stop button)
private void showStopButton(){
((Button)findViewById(R.id.startButton)).setVisibility(View.GONE);
((Button)findViewById(R.id.resetButton)).setVisibility(View.GONE);
((Button)findViewById(R.id.stopButton)).setVisibility(View.VISIBLE);
}
private void hideStopButton(){
((Button)findViewById(R.id.startButton)).setVisibility(View.VISIBLE);
((Button)findViewById(R.id.resetButton)).setVisibility(View.VISIBLE);
((Button)findViewById(R.id.stopButton)).setVisibility(View.GONE);
}
//-------- time from MiliSeconds to regular time ---------------------------------
private void updateTimer (float time){
secs = (long)(time/1000);
mins = (long)((time/1000)/60);
hrs = (long)(((time/1000)/60)/60);
/* Setting the timer text to the elapsed time */
((TextView)findViewById(R.id.timerHs)).setText(hours + ":");
((TextView)findViewById(R.id.timer)).setText(minutes + ":" + seconds);
((TextView)findViewById(R.id.timerMs)).setText(":" + milliseconds);
/* Convert the seconds to String
* and format to ensure it has
* a leading zero when required
*/
secs = secs % 60;
seconds=String.valueOf(secs);
if(secs == 0){
seconds = "00";
}
if(secs <10 && secs > 0){
seconds = "0"+seconds;
}
/* Convert the minutes to String and format the String */
mins = mins % 60;
minutes=String.valueOf(mins);
if(mins == 0){
minutes = "00";
}
if(mins <10 && mins > 0){
minutes = "0"+minutes;
}
/* Convert the hours to String and format the String */
hours=String.valueOf(hrs);
if(hrs == 0){
hours = "00";
}
if(hrs <10 && hrs > 0){
hours = "0"+hours;
}
/* milliseconds */
milliseconds = String.valueOf((long)time);
if(milliseconds.length()==3){
milliseconds = "0"+milliseconds;
}
if(milliseconds.length()<=1){
milliseconds = "00";
}
milliseconds = milliseconds.substring(milliseconds.length()-3, milliseconds.length()-1);
}
//------------- Timer Runnnable ---------------------------------------------------
private Runnable startTimer = new Runnable() {
public void run() {
elapsedTime = System.currentTimeMillis() - startTime;
updateTimer(elapsedTime);
mHandler.postDelayed(this,REFRESH_RATE);
}
};
//------------------ screen orientation fix ---------------------------------------
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
TextView timer = (TextView) findViewById(R.id.timer);
timer.setTextSize(TypedValue.COMPLEX_UNIT_SP, 90);
TextView timerMs = (TextView) findViewById(R.id.timerMs);
timerMs.setTextSize(TypedValue.COMPLEX_UNIT_SP, 40);
}
else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
TextView timer = (TextView) findViewById(R.id.timer);
timer.setTextSize(TypedValue.COMPLEX_UNIT_SP, 70);
TextView timerMs = (TextView) findViewById(R.id.timerMs);
timerMs.setTextSize(TypedValue.COMPLEX_UNIT_SP, 30);
}
}
}
我的Xml文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/parentFrameLayout">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/linearLayout">
<LinearLayout
android:orientation="horizontal"
android:gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="@+id/timerHs"
style="@style/timerText"
android:layout_width="wrap_content"
android:paddingTop="30sp"
android:text="@string/timerHs"
android:textSize="30sp"
android:paddingRight="5sp"
android:paddingBottom="60sp" />
<TextView
style="@style/timerText"
android:text="@string/timer"
android:id="@+id/timer"
android:layout_width="wrap_content" >
</TextView>
<TextView
style="@style/timerText"
android:text="@string/timerMs"
android:id="@+id/timerMs"
android:textSize="30sp"
android:paddingTop="30sp"
android:layout_width="wrap_content"
android:paddingLeft="5sp"
android:paddingBottom="60sp">
</TextView>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="@drawable/buttonarea">
<Button
style="@style/buttonText"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:background="@drawable/stopbuttonstates"
android:textColor="#7A1100"
android:shadowColor="#DF726E"
android:text="@string/stopText"
android:id="@+id/stopButton"
android:visibility="gone"
android:onClick="stopClick">
</Button>
<Button
style="@style/buttonText"
android:layout_marginLeft="5dp"
android:background="@drawable/startbuttonstates"
android:textColor="#000000"
android:shadowColor="#FBEBC5"
android:text="@string/startText"
android:id="@+id/startButton"
android:onClick="startClick">
</Button>
<Button
style="@style/buttonText"
android:layout_marginRight="5dp"
android:background="@drawable/resetbuttonstates"
android:textColor="#2E2E2E"
android:shadowColor="#959597"
android:text="@string/resetText"
android:id="@+id/resetButton"
android:onClick="resetClick">
</Button>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal">
<ImageView
android:src="@drawable/hline"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:layout_marginBottom="10dp"
android:layout_width="wrap_content">
</ImageView>
</LinearLayout>
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:id="@+id/scrollView">
<TextView
style="@style/backgroundText"
android:text="@string/backgroundText"
android:id="@+id/backgroundText">
</TextView>
</ScrollView>
</LinearLayout>
</FrameLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" >
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#000000">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/adsText">
</TextView>
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
的字符串:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, StopwatchActivity!</string>
<string name="app_name">Stopwatch</string>
<string name="timer">00:00</string>
<string name="timerMs">:00</string>
<string name="timerHs">00:</string>
<string name="startText">start</string>
<string name="resetText">reset</string>
<string name="stopText">stop</string>
<string name="backgroundText">Stopwatch</string>
<string name="adsText">Ads Go Here</string>
<string name="menu_settings">Settings</string>
<string name="title_activity_main">MainActivity</string>
日志:(应用程序在此日志的第一次启动时崩溃)
09-27 17:05:54.980: D/dalvikvm(920): GC_CONCURRENT freed 65K, 3% free 8410K/8583K, paused 107ms+8ms, total 211ms
09-27 17:05:54.980: D/dalvikvm(920): WAIT_FOR_CONCURRENT_GC blocked 65ms
09-27 17:05:55.271: D/dalvikvm(920): GC_FOR_ALLOC freed 2K, 3% free 8760K/8967K, paused 44ms, total 45ms
09-27 17:05:55.781: I/Choreographer(920): Skipped 57 frames! The application may be doing too much work on its main thread.
09-27 17:05:55.822: D/gralloc_goldfish(920): Emulator without GPU emulation detected.
09-27 17:05:56.180: I/Choreographer(920): Skipped 34 frames! The application may be doing too much work on its main thread.
09-27 17:06:10.250: D/AndroidRuntime(920): Shutting down VM
09-27 17:06:10.250: W/dalvikvm(920): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
09-27 17:06:10.280: E/AndroidRuntime(920): FATAL EXCEPTION: main
09-27 17:06:10.280: E/AndroidRuntime(920): java.lang.StringIndexOutOfBoundsException: length=2; regionStart=-1; regionLength=2
09-27 17:06:10.280: E/AndroidRuntime(920): at java.lang.String.startEndAndLength(String.java:593)
09-27 17:06:10.280: E/AndroidRuntime(920): at java.lang.String.substring(String.java:1474)
09-27 17:06:10.280: E/AndroidRuntime(920): at com.tutorial.stopwatch.MainActivity.updateTimer(MainActivity.java:178)
09-27 17:06:10.280: E/AndroidRuntime(920): at com.tutorial.stopwatch.MainActivity.access$3(MainActivity.java:125)
09-27 17:06:10.280: E/AndroidRuntime(920): at com.tutorial.stopwatch.MainActivity$1.run(MainActivity.java:190)
09-27 17:06:10.280: E/AndroidRuntime(920): at android.os.Handler.handleCallback(Handler.java:615)
09-27 17:06:10.280: E/AndroidRuntime(920): at android.os.Handler.dispatchMessage(Handler.java:92)
09-27 17:06:10.280: E/AndroidRuntime(920): at android.os.Looper.loop(Looper.java:137)
09-27 17:06:10.280: E/AndroidRuntime(920): at android.app.ActivityThread.main(ActivityThread.java:4745)
09-27 17:06:10.280: E/AndroidRuntime(920): at java.lang.reflect.Method.invokeNative(Native Method)
09-27 17:06:10.280: E/AndroidRuntime(920): at java.lang.reflect.Method.invoke(Method.java:511)
09-27 17:06:10.280: E/AndroidRuntime(920): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
09-27 17:06:10.280: E/AndroidRuntime(920): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
09-27 17:06:10.280: E/AndroidRuntime(920): at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:1)
这是抛出StringIndexOutOfBoundsException
:
milliseconds = milliseconds.substring(milliseconds.length()-3, milliseconds.length()-1);
在此之前,如果长度小于1,则将毫秒设置为“00”。请记住,如果毫秒长度小于3(如果它是“00”),那么在下一行你将从-1开始接受一个子串,这会引发异常。
也许你想要的是这个:
milliseconds = milliseconds.substring(milliseconds.length()-2, milliseconds.length());
答案 1 :(得分:1)
这里的行是错误的
milliseconds = milliseconds.substring(milliseconds.length()-3, milliseconds.length()-1);
当miliseconds设置为&#34; 00&#34;然后你将从-1开始子串到1.
你应该重新考虑你想要做的事情,并抓住这个案例。
也许这个:
milliseconds = String.valueOf((long)time);
if(milliseconds.length()==3){
milliseconds = "0"+milliseconds;
}
if(milliseconds.length()<=1){
milliseconds = "00";
}
else // Now wont substring when length <= 1 as there is no need.
{
milliseconds = milliseconds.substring(milliseconds.length()-3, milliseconds.length()-1);
}