Question

I'm a beginner at both Android Development and StackOverflow so please don't shoot me if I step on any toes ! I am trying to get a simple app working where a user pushes a button and a displayed integer increments while the button is held down, and the button stays as is when the button is released. Ground breaking stuff !

So I went with the following approach :

public class MainActivity extends Activity {
Button pushBtn;
TextView textView,inc_txt;
String TAG ="Button Act";
int inc_val =0;
public Handler myHandler=null;
boolean finishedThread = false;
boolean threadRunning = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main); 
    Log.i(TAG, "in onCreate");

}
@Override
protected void onStart() {
    // TODO Auto-generated method stub
    super.onStart();
    Log.i(TAG, "in onStart");
    pushBtn=(Button)findViewById(R.id.Btn_Push);
    Log.i(TAG, "in onStart 1");
    textView=(TextView)findViewById(R.id.testText);
    inc_txt=(TextView)findViewById(R.id.increment_text);


    pushBtn.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent Button_event) {

            Log.i(TAG, "in onTouch Event");
            switch (Button_event.getAction()) {
            case MotionEvent.ACTION_DOWN:

                Log.i(TAG, " ..Down");
                textView.setText("Button Down");
                if(myHandler!=null)
                {
                    Log.i(TAG, "Handle was not null");
                    return true;
                }
                myHandler=new Handler();
                Log.i(TAG, "postingAction Original");
                myHandler.postDelayed(pushedAction, 250);


                return true;

            case MotionEvent.ACTION_UP:

                textView.setText("Button Up");
                myHandler.removeCallbacks(pushedAction);
                myHandler=null;


                return true;


            default:
                textView.setText("Default");
                myHandler=null;
                break;
            }
            return false;
        }


    });
    Log.i(TAG, "in onStart 3");
}

Runnable pushedAction= new Runnable() {

    @Override
    public void run() {
        inc_txt.setText(Integer.toString(inc_val));
        inc_val++;
        Log.i(TAG, "postingAction Repeat");
        myHandler.postDelayed(this, 250);
        // TODO Auto-generated method stub

    }
};

And Happy days this works on the AVD (4.2.2). (Its just a Button and two TextViews)

But When I went to put this onto my Nexus 4 (4.3), the original postDelayed (in "onStart") works fine , but the second postDelayed, the recursive call in the runnable itself throws a null pointer exception.

See the Logcat:

08-08 10:08:14.245: I/Button Act(19992): in onTouch Event 08-08 10:08:14.245: I/Button Act(19992): ..Down 08-08 10:08:14.245: I/Button Act(19992): postingAction Original 08-08 10:08:14.275: I/Button Act(19992): in onTouch Event 08-08 10:08:14.385: I/Button Act(19992): in onTouch Event 08-08 10:08:14.405: I/Button Act(19992): in onTouch Event 08-08 10:08:14.425: I/Button Act(19992): in onTouch Event 08-08 10:08:14.495: I/Button Act(19992): postingAction Repeat 08-08 10:08:14.495: D/AndroidRuntime(19992): Shutting down VM 08-08 10:08:14.495: W/dalvikvm(19992): threadid=1: thread exiting with uncaught exception (group=0x4152c700) 08-08 10:08:14.495: E/AndroidRuntime(19992): FATAL EXCEPTION: main 08-08 10:08:14.495: E/AndroidRuntime(19992): java.lang.NullPointerException 08-08 10:08:14.495: E/AndroidRuntime(19992): at com.example.buttonexperiments.MainActivity$1.run(MainActivity.java:94) 08-08 10:08:14.495: E/AndroidRuntime(19992): at android.os.Handler.handleCallback(Handler.java:730) 08-08 10:08:14.495: E/AndroidRuntime(19992): at android.os.Handler.dispatchMessage(Handler.java:92) 08-08 10:08:14.495: E/AndroidRuntime(19992): at android.os.Looper.loop(Looper.java:137) 08-08 10:08:14.495: E/AndroidRuntime(19992): at android.app.ActivityThread.main(ActivityThread.java:5103) 08-08 10:08:14.495: E/AndroidRuntime(19992): at java.lang.reflect.Method.invokeNative(Native Method) 08-08 10:08:14.495: E/AndroidRuntime(19992): at java.lang.reflect.Method.invoke(Method.java:525) 08-08 10:08:14.495: E/AndroidRuntime(19992): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 08-08 10:08:14.495: E/AndroidRuntime(19992): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 08-08 10:08:14.495: E/AndroidRuntime(19992): at dalvik.system.NativeStart.main(Native Method)

Can anyone see what I am doing wrong? All help appreciated. Sorry if I made a mess of asking the question ( The LogCat .. I know )! Safe Travels !

Was it helpful?

Solution

I think the problem might be that in the default case of your switch case and in action up you put myHandler to null. Is there any reason why you do that? You create a new Handler everytime you touch and null it everytime. Why would you do that? I would just put a myHandler=new Handler(); in your onCreate and leave it that way, no need to put it to null and create new one.

OTHER TIPS

try { 
  //  Write your code here which cause the NullPointerException error ...
} catch (NullPointerException npe) { 
  // Just leave this section ...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top