NullPointerException视图问题

时间:2011-06-17 09:29:14

标签: android view timer nullpointerexception

我认为我还没有得到关于如何编码这些视图的内容。这是我第三次来过去发布过去3天里的一个问题! :S

无论如何,我的问题如下。

编辑: 这个方法中的代码,在按下按钮时执行: (注意到重点)

>>  setContentView(R.layout.stop);
>>  timer = (TextView) findViewById(R.id.timer2);
    GPSMain.button = (Button) findViewById(R.id.stopbutton);

    startService(new Intent(context, Timer.class));

}

这是在“startService”调用中执行的Timer类: (再次指出重要点)

public class Timer extends Service {

static int totalSeconds = 0;
private int hour = 0;
private int min = 0;
private int sec = 0;
String mTimeFormat = "%02d:%02d:%02d";
final private Handler mHandler = new Handler();
static String timeTaken;
Context context = this;

Runnable mUpdateTime = new Runnable() {
    public void run() { updateTimeView(); }
};

@Override
public void onCreate() {

    Toast.makeText(context, "Timer Started", Toast.LENGTH_LONG).show();

    mHandler.postDelayed(mUpdateTime, 1000);
}

public void updateTimeView() {
    totalSeconds += 1;
    sec += 1;
    if(sec >= 60) {
        sec = 0;
        min += 1;
        if (min >= 60) {
            min = 0;
            hour += 1;
        }
    }
>>  timeTaken = String.format(mTimeFormat, hour, min, sec);
>>  GPSMain.timer.setText("Time Taken: "+timeTaken);
    mHandler.postDelayed(mUpdateTime, 1000);

}

@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}
}

logcat在以下代码行返回NullPointerException:

GPSMain.timer.setText("Time Taken: "+timeTaken);

如果我删除了那行代码,代码正确执行*,我说得好,因为它一直执行到应用程序代码的末尾,但我想将计时器打印到屏幕上的原因是计数是因为我需要确保它正常运行。

*它不仅运行正常,而且显示定时器文本视图,其中包含xml中默认定义的字符串。只有当我尝试从崩溃的java中更新它时才会这样。

以下是此时代码引用的完整xml文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
    android:id="@+id/stopbutton"
    android:layout_width="100px" 
    android:layout_height="100px" 
    android:text="Stop"
    android:layout_centerInParent="true"
/>
<TextView  
    android:id="@+id/timer2"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="Time Taken:       unknown"
    android:layout_below="@+id/timer"
    />
</RelativeLayout>

UPDATE!

MyTimer类:

@SuppressWarnings("unchecked")
public class MyTimer extends AsyncTask { 

Timer _timerTask = new Timer();
static int totalSeconds = 0, hour = 0, min = 0, sec = 0;
static String mTimeFormat = "%02d:%02d:%02d";
static String timeTakenString;

@Override
protected Object doInBackground(Object... params) {

        TimerTask timer = new TimerTask() {

            @Override
            public void run() {

                totalSeconds += 1;
                sec += 1;
                if(sec >= 60) {
                    sec = 0;
                    min += 1;
                    if (min >= 60) {
                        min = 0;
                        hour += 1;
                    }
                }
                timeTakenString = String.format(mTimeFormat, hour, min, sec);
                GPSMain.timer.setText("Time Taken: "+GPSMain.timeTaken);

            }
        };
         (_timerTask).scheduleAtFixedRate(timer,1000,1000);

    return null;
}

}

启动计时器线程的方法:

void startService(){

    setContentView(R.layout.stop);

    timer = (TextView) findViewById(R.id.timer2);

    GPSMain.button = (Button) findViewById(R.id.stopbutton);

    new MyTimer().execute();

}

3 个答案:

答案 0 :(得分:2)

为什么你需要Service?你为什么不用AsyncTask?当您需要在后台运行某些内容时,通常会使用服务,而不向用户显示布局。您的应用程序向用户显示数据,因此解决问题的最佳方法是运行单独的线程,而不是服务。希望这会有所帮助。

答案 1 :(得分:1)

您可以使用TimerTask代替Service。这是代码..

TimerTask timer = new TimerTask() {

            @Override
            public void run() {

                        // Here you can update your UI
    }
 }

Timer _timerTask = new Timer();
        _timerTask.scheduleAtFixedRate(timer,60000,60000);

答案 2 :(得分:1)

好吧,我真的不太了解服务,但在所有情况下,你应该只从UI线程访问UI。

我的情况,我觉得有按钮和服务的Activity是两个不同的类,服务没有任何活动对象。
我认为您从服务设置文本视图的方式可能是一个问题。但同样,我对服务知之甚少。

另一方面,我同意Egor,除非你有很多活动并且每个人都在做很多网络活动,所以AsyncTask就是你的选择。

希望有所帮助。