0

我遇到了无法解决的 nullPointerException 问题。有人可以帮忙吗?

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);
        }


}

登录类

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{}
    }
}

xml 文件

<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>

和错误日志

    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

似乎有些按钮监听器确实存在问题,但阅读帖子并没有给我预期的解决方案。谢谢你的帮助。

4

5 回答 5

5

你必须先setContentview(R.layout.XXXX)在super之后使用,然后才可以使用资源。否则你会得到空指针异常..登录活动中缺少设置内容视图....

于 2013-05-30T13:47:21.217 回答
3

您正在尝试将相同的按钮变量设置为布局上的两个不同按钮:

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

您需要为这些创建两个单独的变量。

编辑经过多次辩论,我再次尝试了一些代码并意识到问题出在哪里。

我已将按钮设置如下:

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
     }
});

这行不通!!!然而,经过多次辩论,我想尝试以下其他方法:

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
     }
});

另一方面,这确实有效。

于 2013-05-30T13:47:12.107 回答
2

您在这里的问题,或者至少一个问题是您没有在Login. 因此,您尝试使用的任何 View ( BUtton,EditText等...) 都将是null

在尝试设置之前onCreate()调用setContentView(R.layout.yourLayout);Views

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

它们Views存在于内部,直到您使用或调用膨胀之后LayoutnulllayoutinflatersetContentView(...);

另外,由于您是新手

  • 请阅读常见问题解答
  • 发布代码时,请选择您认为最相关的部分并将其与相关的 logcat 和错误消息一起发布。如果需要,我们会很乐意要求更多
  • 如果您发布多个课程,请将它们分开而不是一个长部分,以便会员阅读
  • 通常不需要所有的 import 语句

这些并不是真正的问题,但会帮助您获得更好/更快的答案。

于 2013-05-30T13:47:13.683 回答
1

我注意到您的登录活动中没有 setContentView。通常,如果人们在调用 setContentView 之前调用 findViewById(...),就会出现空指针错误。在您的情况下,您甚至没有 setContentView()。

于 2013-05-30T13:54:41.637 回答
0

如果您的 OK 按钮没有响应点击,则监听器实例可能正在被垃圾收集器清除。

将您的侦听器创建为类级别属性:

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

然后在 onCreate() 中分配它们:

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

由于侦听器在活动中具有引用,因此它们不会被垃圾收集。我在单独的线程上启动媒体播放器时遇到了类似的问题。玩家被杀死是因为我没有保留对线程的引用,所以垃圾收集器看到了一个未引用的对象树并将其清除。

于 2013-05-30T14:47:24.693 回答