NullPointerException Issue with view
I think there is something that I'm just not yet getting about how these Views are to be coded. This is the third time I have had to come and post a question rearding them in the last 3 days! :S
Anyway, my problem is as follows.
edit: This is the code inside a method that gets executed on a button press: (Points of importance are noted)
>> setContentView(R.layout.stop);
>> timer = (TextView) findViewById(R.id.timer2);
GPSMain.button = (Button) findViewById(R.id.stopbutton);
startService(new Intent(context, Timer.class));
}
This is the Timer class that is executed in the "startService" call: (Again points of importance are noted)
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;
}
}
The logcat returns a NullPointerException on the following line of code:
GPSMain.timer.setText("Time Taken: "+timeTaken);
If I remove that line of code the code executes properly*, well I say properly because it executes all the way to the end of the application code, but the reason that I want to print the timer to the screen as it is counting is because I need to make sure that it is functioning correctly.
*not only does it run properly but it displays the timer text view with it's default defined string from the xml. It's only when I try to update it from the java that it crashes.
开发者_运维百科Here is the full xml file that the code is referencing at this point:
<?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!
The MyTimer Class:
@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;
}
}
The method to start the timer thread:
void startService(){
setContentView(R.layout.stop);
timer = (TextView) findViewById(R.id.timer2);
GPSMain.button = (Button) findViewById(R.id.stopbutton);
new MyTimer().execute();
}
Why do you need a Service
here? Why don't you just use AsyncTask
? A Service is usually used when you need to run something in background, with no layout shown to user. Your application shows data to user, so the best way for you to solve your problem is to run a separate thread, not a service. Hope this helps.
You can use TimerTask instead of Service . Here is the code ..
TimerTask timer = new TimerTask() {
@Override
public void run() {
// Here you can update your UI
}
}
Timer _timerTask = new Timer();
_timerTask.scheduleAtFixedRate(timer,60000,60000);
Well, I seriously don't know much about services, but in all cases, you should be accessing UI only from the UI thread.
I your case, I feel the Activity that has the button and the Service are two different classes, with the service not possessing any object of the activity. I think the way you're setting the text view from a service may be an issue. but again, i don't know much about services.
On the other note, I agree with Egor, unless you have a lot of activities and each keeps doing a lot of network activity, AsyncTask is the way to go.
精彩评论