Search code examples
javaandroidclassonclicklistenerlogcat

Android app force closes - setOnClickListener [simple app] [beginner]


Program functions as normal on start up. As soon as button is clicked, app force closes and the log cat (at bottom) is shown.

XML File - layout is fully functional

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.figurehowtodo.MainActivity$PlaceholderFragment" >

<TextView
    android:id="@+id/produceText1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello_world" />

<Button
    android:id="@+id/myactualbutton"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="ClickMe" />

</LinearLayout>

MainActivity.java

package com.example.figurehowtodo;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

    Button mybutton;
    TextView tvView;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_main);
        mybutton = (Button) findViewById(R.id.myactualbutton);
        tvView = (TextView) findViewById(R.id.produceText1);
        mybutton.setOnClickListener(new MyOwnOnClickListener());
    }

}

MyOwnOnClickListener.java

package com.example.figurehowtodo;

import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

public class MyOwnOnClickListener extends Activity implements OnClickListener{
    //int id;
    TextView id2;
    //TextView id3;

    /* MainActivity caller;
    public MyOwnOnClickListener() {
        addiTion();
        IGNORE THIS BIT
    } */

    public void onClick(View v) {
        addiTion(v);
    }

    public void addiTion(View v){
        //id = hello.getId();
        id2 = (TextView) findViewById(R.id.produceText1);
        id2.setText("fgdsgdfhgdfh");
    }
}

Logcat:

03-27 20:56:31.710: E/AndroidRuntime(2132): FATAL EXCEPTION: main
03-27 20:56:31.710: E/AndroidRuntime(2132): java.lang.NullPointerException
03-27 20:56:31.710: E/AndroidRuntime(2132):     at android.app.Activity.findViewById(Activity.java:1647)
03-27 20:56:31.710: E/AndroidRuntime(2132):     at com.example.figurehowtodo.MyOwnOnClickListener.addiTion(MyOwnOnClickListener.java:29)
03-27 20:56:31.710: E/AndroidRuntime(2132):     at com.example.figurehowtodo.MyOwnOnClickListener.onClick(MyOwnOnClickListener.java:22)
03-27 20:56:31.710: E/AndroidRuntime(2132):     at android.view.View.performClick(View.java:2485)
03-27 20:56:31.710: E/AndroidRuntime(2132):     at android.view.View$PerformClick.run(View.java:9080)
03-27 20:56:31.710: E/AndroidRuntime(2132):     at android.os.Handler.handleCallback(Handler.java:587)
03-27 20:56:31.710: E/AndroidRuntime(2132):     at android.os.Handler.dispatchMessage(Handler.java:92)
03-27 20:56:31.710: E/AndroidRuntime(2132):     at android.os.Looper.loop(Looper.java:123)
03-27 20:56:31.710: E/AndroidRuntime(2132):     at android.app.ActivityThread.main(ActivityThread.java:3683)
03-27 20:56:31.710: E/AndroidRuntime(2132):     at java.lang.reflect.Method.invokeNative(Native Method)
03-27 20:56:31.710: E/AndroidRuntime(2132):     at java.lang.reflect.Method.invoke(Method.java:507)
03-27 20:56:31.710: E/AndroidRuntime(2132):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
03-27 20:56:31.710: E/AndroidRuntime(2132):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
03-27 20:56:31.710: E/AndroidRuntime(2132):     at dalvik.system.NativeStart.main(Native Method)
03-27 20:56:31.720: W/ActivityManager(61):   Force finishing activity com.example.figurehowtodo/.MainActivity
03-27 20:56:32.230: W/ActivityManager(61): Activity pause timeout for HistoryRecord{40698748 com.example.figurehowtodo/.MainActivity}
03-27 20:56:38.440: D/dalvikvm(299): GC_EXPLICIT freed 6K, 54% free 2544K/5511K, external 1625K/2137K, paused 55ms
03-27 20:56:43.380: W/ActivityManager(61): Activity destroy timeout for HistoryRecord{40698748 com.example.figurehowtodo/.MainActivity}
03-27 20:56:43.480: D/dalvikvm(311): GC_EXPLICIT freed 2K, 54% free 2537K/5511K, external 1625K/2137K, paused 78ms
03-27 20:56:48.460: D/dalvikvm(220): GC_EXPLICIT freed 184K, 54% free 2764K/5959K, external 2202K/2671K, paused 56ms

Solution

  • You have not set you content view for your activity class MyOwnOnClickListener. So method findViewById() cannot find the view you are passing as argument.

    I think the MyOwnOnClickListener class shouldn't be an Activity class, but just a listener. You can pass a reference to the TextView to the listener to use it.

    Or you can implement the listener in your MainActivity class and suppress the MyOwnOnClickListener class.

    public class MainActivity extends Activity implements OnClickListener {
        Button mybutton;
        TextView tvView;
    
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.fragment_main);
            mybutton = (Button) findViewById(R.id.myactualbutton);
            tvView = (TextView) findViewById(R.id.produceText1);
            mybutton.setOnClickListener(this);
        }
    
        public void onClick(View v) {
            addiTion(v);
        }
    
        public void addiTion(View v){
            tvView.setText("fgdsgdfhgdfh");
        }
    }
    

    EDIT: If you want to use a listener class, just keep your MainActivity as it is, change only the call to the MyOwnOnClickListener to pass the tvView reference, and change the MyOwnOnClickListener class like this:

    public class MyOwnOnClickListener implements OnClickListener{
    TextView id2;
    
        // MainActivity caller;
        public MyOwnOnClickListener(TextView id2) {
            this.id2 = id2;
        }
    
        public void onClick(View v) {
            switch(v.getId()) {
            case R.id.produceText1:
                id2.setText("fgdsgdfhgdfh");
                break;
            // Other cases here...
            default:
                // Whatever you want to manage the situation...
            }
        }
    }
    

    It should work...