fred
fred

Reputation: 1

nullPointerException with button onclick listener

i'm having nullPointerException issue that i can't resolve. could someone help please?

my code:

package gsb.com;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.widget.TextView;

the main class

public class ActivitePrincipale extends Activity {
    //Variables pour l'authentification
        private TextView tv;
        public static final int RESULT_Main = 1;

        @Override
        protected void onCreate(Bundle savedInstanceState) 
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activite_principale);

            //Authentification
            //Appel de la page de Login 
            startActivityForResult(new Intent(ActivitePrincipale.this, Login.class), RESULT_Main);
            //tv = new TextView(this);
            //setContentView(tv);
        }

        //Procédure d'authentification
        private void startup(Intent i) 
        {
            // Récupère l'identifiant        
            int user = i.getIntExtra("userid",-1);

            //Affiche les identifiants de l'utilisateur
            tv.setText("UserID: "+String.valueOf(user)+" logged in");
        }

        protected void onActivityResult(int requestCode, int resultCode, Intent data) 
        { 
            if(requestCode == RESULT_Main && resultCode == RESULT_CANCELED)  
                finish(); 
            else 
                startup(data);
        }


}

the login class

package gsb.com;
import gsb.com.R;


import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.protocol.HTTP;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class Login extends Activity
{
    // Lien vers votre page php sur le serveur
    private static final String UPDATE_URL  = some ip
    public ProgressDialog progressDialog;
    private EditText UserEditText;
    private EditText PassEditText;
    private android.widget.Button button;

    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        Log.i("Info","Dans Login - onCreate --------------");
        //initialisation d'une progress bar
        progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("Patientez svp...");
        progressDialog.setIndeterminate(true);
        progressDialog.setCancelable(false);

        //recuperation des elements de la vue
        UserEditText = (EditText)findViewById(R.id.username);
        if (UserEditText == null) { Log.w("Info", "UserEditText est null --------------"); }
        PassEditText = (EditText)findViewById(R.id.password);
        if (PassEditText == null) { Log.w("Info", "PassEditText est null --------------"); }
        button = (Button)findViewById(R.id.okbutton);
        if (button == null) { Log.w("Info", "button est null --------------"); }

        //definition du listener du bouton ok
        button.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {

                int userSize = UserEditText.getText().length();
                int passSize = PassEditText.getText().length();

                //si les deux champs sont complétés
                if(userSize > 0 && passSize > 0){
                    progressDialog.show();
                    String user = UserEditText.getText().toString();
                    String pass = PassEditText.getText().toString();
                    //appel de la fonction doLogin qui va appeler le script connect.php
                    doLogin(user,pass);
                }
                else {
                    createDialog("Erreur !!", "SVP Entrez un nom d'utilisateur et un mot de passe.");
                }
            }
        });

        button = (Button)findViewById(R.id.cancelbutton);
        //creation du listener du bouton annuler pour sortir de l'appli
        button.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {

                quit(false, null);
            }
        });
    }

    private void quit(boolean succes, Intent i){
        //envoi d'un resultat qui va permettre de quitter l'appli
        setResult((succes)? Activity.RESULT_OK : Activity.RESULT_CANCELED,i);
        finish();
    }

    private void createDialog(String title, String text){
        //affichage d'un popup
        AlertDialog ad  = new AlertDialog.Builder(this)
                .setPositiveButton("Ok", null).setTitle(title).setMessage(text)
                .create();
        ad.show();
    }

    private void doLogin(final String login, final String pass){
        final String pw = md5(pass);
        //final String pw = pass;

        //creation d'un thread
        Thread t = new Thread(){
            public void run(){
                Looper.prepare();
                //connexion au serveur pour communiquer avec le php
                DefaultHttpClient client = new DefaultHttpClient();
                HttpConnectionParams.setConnectionTimeout(client.getParams(),15000);

                HttpResponse response;
                HttpEntity entity;

                try{
                    //on etablit un lien avec le script connect.php
                    HttpPost post = new HttpPost(UPDATE_URL);
                    List<NameValuePair> nvp = new ArrayList<NameValuePair>();
                    nvp.add(new BasicNameValuePair("username",login));
                    nvp.add(new BasicNameValuePair("password",pw));
                    post.setHeader("Content-Type", "application/x-www-form-urlencoded");

                    //passage des params login et password qui vont etre recup par le script php en Post
                    post.setEntity(new UrlEncodedFormEntity(nvp, HTTP.UTF_8));

                    //recup du resultat du script
                    response = client.execute(post);
                    entity = response.getEntity();
                    InputStream is = entity.getContent();

                    //appel d'une fonction pour traduire la reponse
                    read(is);
                    is.close();

                    if(entity != null){
                        entity.consumeContent();
                    }
                }
                catch(Exception e){
                    progressDialog.dismiss();
                    createDialog("Error", "Impossible d'etablir une connexion");
                }
                Looper.loop();
            }
        };
        t.start();
    }

    private void read(InputStream inpStr){
        //traduction du resultat du flux
        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser sp;

        try{
            sp = spf.newSAXParser();
            XMLReader xr = sp.getXMLReader();

            //classe definie plus bas
            LoginContentHandler lch = new LoginContentHandler();

            xr.setContentHandler(lch);
            xr.parse(new InputSource(inpStr));          
        }
        catch(ParserConfigurationException e){}
        catch(SAXException e){}
        catch(IOException e){}
    }

    private String md5(String in) {

        MessageDigest digest;

        try {

            digest = MessageDigest.getInstance("MD5");

            digest.reset();

            digest.update(in.getBytes());

            byte[] a = digest.digest();

            int len = a.length;

            StringBuilder sb = new StringBuilder(len << 1);

            for (int i = 0; i < len; i++) {
                sb.append(Character.forDigit((a[i] & 0xf0) >> 4, 16));
                sb.append(Character.forDigit(a[i] & 0x0f, 16));
            }

            return sb.toString();

        }
        catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        return null;
    }

    private class LoginContentHandler extends DefaultHandler {
        //Traite le retour du script connect.php

        private boolean in_loginTag = false;
        private int userID;
        private boolean error_occured = false;

        public void startElement(String n, String l, String q, Attributes a) throws SAXException {

                if(l=="login"){
                    in_loginTag = true;
                }

                if(l=="error"){
                    progressDialog.dismiss();

                    switch(Integer.parseInt(a.getValue("value"))){
                    case 1:
                        createDialog("Error", "Impossible de se connecter à la base de données");
                        break;
                    case 2:
                        createDialog("Error", "Erreur dans la base de données, Table manquante");
                        break;
                    case 3:
                        createDialog("Error", "Login ou mot de passe invalide !");
                        break;
                    }
                    error_occured = true;
                }

                if(l=="user" && in_loginTag && a.getValue("id")!=""){
                    //si tout est ok on recup l'id de l'utilisateur
                    userID = Integer.parseInt(a.getValue("id"));
                }                           
        }

        public void endElement(String n, String l, String q) throws SAXException {
            //on renvoie l'id si tout est ok
            if(l=="login"){
                in_loginTag = false;

                if(! error_occured){
                    progressDialog.dismiss();
                    Intent i = new Intent();
                    i.putExtra("userid", userID);
                    quit(true, i);
                }
            }
        }

        public void characters(char ch[], int start, int length){}
        public void startDocument() throws SAXException{}
        public void endDocument() throws SAXException{}
    }
}

the xml files

<RelativeLayout 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: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=".ActivitePrincipale" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="14dp"
        android:text="@string/connexion_form_title" />

    <EditText
        android:id="@+id/password"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/username"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="25dp"
        android:ems="10"
        android:inputType="textPassword"
        android:text="@string/password_text_field"/>

    <EditText
        android:id="@+id/username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="34dp"
        android:inputType="text"
        android:ems="10" 
        android:text="@string/username_text_field"/>

    <Button
        android:id="@+id/okbutton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/password"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="66dp"
        android:text="@string/connexion_button" />

    <Button
        android:id="@+id/cancelbutton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/okbutton"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="30dp"
        android:text="@string/cancel_button" />

</RelativeLayout>

the manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="gsb.com"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="gsb.com.ActivitePrincipale"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="gsb.com.Login" android:label="Login">

            <intent-filter>

                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />

            </intent-filter>

        </activity>
    </application>    

</manifest>

and the error logs

    05-30 13:29:37.252: I/Info(712): Dans Login - onCreate --------------
    05-30 13:29:37.272: W/Info(712): UserEditText est null --------------
    05-30 13:29:37.272: W/Info(712): PassEditText est null --------------
    05-30 13:29:37.282: W/Info(712): button est null --------------
    05-30 13:29:37.304: D/AndroidRuntime(712): Shutting down VM
    05-30 13:29:37.304: W/dalvikvm(712): threadid=1: thread exiting with uncaught exception (group=0x40015560)
    05-30 13:29:37.342: E/AndroidRuntime(712): FATAL EXCEPTION: main
    05-30 13:29:37.342: E/AndroidRuntime(712): java.lang.RuntimeException: Unable to start activity ComponentInfo{gsb.com/gsb.com.Login}: java.lang.NullPointerException
    05-30 13:29:37.342: E/AndroidRuntime(712):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
    05-30 13:29:37.342: E/AndroidRuntime(712):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
    05-30 13:29:37.342: E/AndroidRuntime(712):  at android.app.ActivityThread.access$1500(ActivityThread.java:117)
    05-30 13:29:37.342: E/AndroidRuntime(712):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
    05-30 13:29:37.342: E/AndroidRuntime(712):  at android.os.Handler.dispatchMessage(Handler.java:99)
    05-30 13:29:37.342: E/AndroidRuntime(712):  at android.os.Looper.loop(Looper.java:123)
    05-30 13:29:37.342: E/AndroidRuntime(712):  at android.app.ActivityThread.main(ActivityThread.java:3683)
    05-30 13:29:37.342: E/AndroidRuntime(712):  at java.lang.reflect.Method.invokeNative(Native Method)
    05-30 13:29:37.342: E/AndroidRuntime(712):  at java.lang.reflect.Method.invoke(Method.java:507)
    05-30 13:29:37.342: E/AndroidRuntime(712):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
    05-30 13:29:37.342: E/AndroidRuntime(712):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
    05-30 13:29:37.342: E/AndroidRuntime(712):  at dalvik.system.NativeStart.main(Native Method)
    05-30 13:29:37.342: E/AndroidRuntime(712): Caused by: java.lang.NullPointerException
    05-30 13:29:37.342: E/AndroidRuntime(712):  at gsb.com.Login.onCreate(Login.java:67)
    05-30 13:29:37.342: E/AndroidRuntime(712):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    05-30 13:29:37.342: E/AndroidRuntime(712):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
    05-30 13:29:37.342: E/AndroidRuntime(712):  ... 11 more

it seems that some did have issues with the button listener but reading the posts did not give me the solution i expected. thanks for your help.

Upvotes: 0

Views: 1417

Answers (5)

TronicZomB
TronicZomB

Reputation: 8747

You are trying to set the same button variable to two different buttons on your layout:

button = (Button)findViewById(R.id.okbutton);
button = (Button)findViewById(R.id.cancelbutton);

You need to create two separate variables for these.

EDIT After much debate, I tried some code again and realized where the issue was.

I had set the Buttons as follows:

button = (Button) findViewById(R.id.ok);
button = (Button) findViewById(R.id.cancel);

button.setOnClickListener(new View.OnClickListener() {
     public void onClick(View v){
         //stuff
     }
});

button.setOnClickListener(new View.OnClickListener() {
     public void onClick(View v){
         // other stuff
     }
});

THIS WILL NOT WORK!!! However after much debate I thought to try something else as follows:

button = (Button) findViewById(R.id.ok);
button.setOnClickListener(new View.OnClickListener() {
     public void onClick(View v){
         //stuff
     }
});

button = (Button) findViewById(R.id.cancel);
button.setOnClickListener(new View.OnClickListener() {
     public void onClick(View v){
         // other stuff
     }
});

This on the other hand DOES work.

Upvotes: 3

Phil Haigh
Phil Haigh

Reputation: 4591

If your OK button is not responding to clicks, it is possible that the listener instance is being swept up by the garbage collector.

Create your listeners as class level properties:

private OnClickListener okListener = new View.OnClickListener() { ... };
private OnClickListener cancelListener = new View.OnClickListener() { ... };

Then assign them in onCreate():

((Button)findViewById(R.id.okbutton)).setOnClickListener(okListener);
((Button)findViewById(R.id.cancelbutton)).setOnClickListener(cancelListener );

As the listeners have references inside the activity, they'll not get garbage collected. I had a similar problem starting a media player on a separate thread. The player got killed because I didn't hold on to a reference to the thread, so the garbage collector saw an unreferenced object tree and cleaned it away.

Upvotes: 0

a_schimpf
a_schimpf

Reputation: 765

I notice you have no setContentView in your Login activity. Usually, people get null-pointer errors with findViewById(...), if they call it before calling setContentView. In your case, you don't even have setContentView().

Upvotes: 1

codeMagic
codeMagic

Reputation: 44571

Your problem here, or at least one is that you don't inflate a layout in Login. So any View you try to use (BUtton, EditText, etc...) will be null

In onCreate() call setContentView(R.layout.yourLayout); BEFORE trying to set Views like

UserEditText = (EditText)findViewById(R.id.username);

The Views exist inside the Layout so they are null until after you have inflated the layout using an inflater or by calling setContentView(...);

Also, just a couple things about the site since you are new

  • Please read the FAQ
  • When posting code, please pick out the parts that you think are most relevant and post those along with a relevant logcat and error messages. We will kindly ask for more if needed
  • If you post multiple classes, please separate them instead of one long section so it is easier for members to read
  • All of the import statements typically aren't necessary

These aren't really a problem but will help you to get better/quicker answers.

Upvotes: 2

Sandeep P
Sandeep P

Reputation: 4411

you have to first use setContentview(R.layout.XXXX) after super, then only you can use resource. other wise you will get the null pointer exception .. set content view is missing in in Login Activity....

Upvotes: 5

Related Questions