【问题标题】:Null Pointer Exception in android when switching activities切换活动时android中的空指针异常
【发布时间】:2011-07-13 17:40:52
【问题描述】:

我刚开始为 Android 编程,当时我的老板让我为他制作一个移动应用程序,所以我在两天内完成了所有这些,并在我做的过程中自学,主要来自这个网站。当我运行我的程序并单击切换下一个活动的按钮时,我不断收到 nullPointerException

第一个活动:

package com.Android.HelpDeskMobileApp;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class HelpDeskFront extends Activity{

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.first);
        Button serviceButton = (Button)findViewById(R.id.serviceButton),
                orderButton = (Button)findViewById(R.id.OrderButton),
                programmingButton = (Button)findViewById(R.id.ProgrammingButton);
        serviceButton.setOnClickListener(buttonListener);
        orderButton.setOnClickListener(buttonListener);
        programmingButton.setOnClickListener(buttonListener);
    }
    private OnClickListener buttonListener = new OnClickListener() {

        public void onClick(View v) {
            String serviceType = null;
            Intent i = new Intent(HelpDeskFront.this, Main.class);
            if (v.getId() == R.id.serviceButton)
                serviceType = "service";
            else if (v.getId() == R.id.OrderButton)
                serviceType = "order";
            else if (v.getId() == R.id.ProgrammingButton)
                serviceType = "programming";
            i.putExtra("serviceType", serviceType);
            startActivityForResult(i, Intent.FILL_IN_DATA);
        };
}

按钮导致我的第二个活动:

package com.Android.HelpDeskMobileApp;

import java.util.ArrayList;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
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 android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class Main extends Activity{

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        final Button send = (Button)findViewById(R.id.sendRequest);
        send.setOnClickListener(buttonListener);
    }
    private OnClickListener buttonListener = new OnClickListener() {

        ArrayList<NameValuePair> data = new ArrayList<NameValuePair>(5);
        final EditText caller = (EditText) findViewById(R.id.CallerEnter), 
                 callExt = (EditText) findViewById(R.id.CallNumberEnter),
                 computerName = (EditText) findViewById(R.id.ComputerNameEnter),
                 location = (EditText) findViewById(R.id.LocationEnter),
                 request = (EditText) findViewById(R.id.RequestEnter);

        public void onClick(View v) {
                    Intent i = getIntent();
        final String serviceType = i.getStringExtra("serviceType");
            Intent intent = new Intent(Main.this, HelpDeskEnd.class);
            final String[] email = {"target emails"};
            data.add(new BasicNameValuePair("Caller: ", textToString(caller)));
            data.add(new BasicNameValuePair("Call Ext: ", textToString(callExt)));
            data.add(new BasicNameValuePair("Computer Name: ", textToString(computerName)));
            data.add(new BasicNameValuePair("Locations: ", textToString(location)));
            data.add(new BasicNameValuePair("Request: ", textToString(request)));
            sendData(data);

            String body = data.get(0).toString() + " " + data.get(1).toString() + " " +
                    data.get(2).toString() + " " + data.get(3).toString() + " " + 
                    data.get(4).toString();
            Mail mail = new Mail("an email", "email password");
            mail.setTo(email);
            mail.setBody(body);
            mail.setFrom("an email");
            mail.setSubject(serviceType);
            try {
                mail.send();
            }
            catch (Exception e) {
                 Log.e("Send Mail", e.getMessage(), e);
            }
            intent.putExtra("serivceType", serviceType);
            startActivity(intent);
        }

    };
    private String textToString(EditText x)
    {
        return x.getText().toString();
    }
    private void sendData(ArrayList<NameValuePair> data)
    {
        try {

            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost("https//www.awebsite.com/phpfile.php");
            httpPost.setEntity(new UrlEncodedFormEntity(data));
            HttpResponse response = httpclient.execute(httpPost);
            Log.i("postData", response.getStatusLine().toString());
        }
        catch (Exception e){
            Log.e("log_tag", "Error: " + e.toString());
        }
    }
}

这可能是一些非常容易解决的问题。谢谢你的帮助。这是我的清单文件,我也不知道它是否有用,但在这里:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.Android.HelpDeskMobileApp"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="12" />
    <uses-permission android:name="android.permission.INTERNET" />

    <application android:icon="@drawable/logo" android:label="@string/app_name">
        <activity android:name=".HelpDeskFront"
                  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:label="@string/app_name" 
                  android:name=".Main">
                  <intent-filter></intent-filter>
        </activity>
        <activity android:label="@string/app_name" 
                  android:name=".HelpDeskEnd">
                  <intent-filter></intent-filter>
        </activity>

    </application>
</manifest>

当我点击按钮从第一个活动转到 .main 活动时发生错误。我已经尝试注释掉代码的不同部分,但我无法弄清楚是什么导致了空指针异常。谢谢。 日志猫:

    07-13 18:37:29.833: ERROR/AndroidRuntime(770): FATAL EXCEPTION: main
07-13 18:37:29.833: ERROR/AndroidRuntime(770): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.Android.HelpDeskMobileApp/com.Android.HelpDeskMobileApp.Main}: java.lang.NullPointerException
07-13 18:37:29.833: ERROR/AndroidRuntime(770):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1672)
07-13 18:37:29.833: ERROR/AndroidRuntime(770):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1764)
07-13 18:37:29.833: ERROR/AndroidRuntime(770):     at android.app.ActivityThread.access$1500(ActivityThread.java:122)
07-13 18:37:29.833: ERROR/AndroidRuntime(770):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1002)
07-13 18:37:29.833: ERROR/AndroidRuntime(770):     at android.os.Handler.dispatchMessage(Handler.java:99)
07-13 18:37:29.833: ERROR/AndroidRuntime(770):     at android.os.Looper.loop(Looper.java:132)
07-13 18:37:29.833: ERROR/AndroidRuntime(770):     at android.app.ActivityThread.main(ActivityThread.java:4025)
07-13 18:37:29.833: ERROR/AndroidRuntime(770):     at java.lang.reflect.Method.invokeNative(Native Method)
07-13 18:37:29.833: ERROR/AndroidRuntime(770):     at java.lang.reflect.Method.invoke(Method.java:491)
07-13 18:37:29.833: ERROR/AndroidRuntime(770):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
07-13 18:37:29.833: ERROR/AndroidRuntime(770):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
07-13 18:37:29.833: ERROR/AndroidRuntime(770):     at dalvik.system.NativeStart.main(Native Method)
07-13 18:37:29.833: ERROR/AndroidRuntime(770): Caused by: java.lang.NullPointerException
07-13 18:37:29.833: ERROR/AndroidRuntime(770):     at android.app.Activity.findViewById(Activity.java:1744)
07-13 18:37:29.833: ERROR/AndroidRuntime(770):     at com.Android.HelpDeskMobileApp.Main$1.<init>(Main.java:35)
07-13 18:37:29.833: ERROR/AndroidRuntime(770):     at com.Android.HelpDeskMobileApp.Main.<init>(Main.java:31)
07-13 18:37:29.833: ERROR/AndroidRuntime(770):     at java.lang.Class.newInstanceImpl(Native Method)
07-13 18:37:29.833: ERROR/AndroidRuntime(770):     at java.lang.Class.newInstance(Class.java:1301)
07-13 18:37:29.833: ERROR/AndroidRuntime(770):     at android.app.Instrumentation.newActivity(Instrumentation.java:1022)
07-13 18:37:29.833: ERROR/AndroidRuntime(770):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1663)
07-13 18:37:29.833: ERROR/AndroidRuntime(770):     ... 11 more

【问题讨论】:

  • 您能否发布您得到的异常,切换到 DDMS 模式并检查您的 logcat 中的错误并在此处发布您的异常
  • 感谢您提供代码,同时向我们展示您的 logcat 输出吗?
  • "Caused by: java.lang.NullPointerException ... at com.Android.HelpDeskMobileApp.Main.(Main.java:31)" Main 的第 31 行是什么?
  • 我看到并尝试将接收 Intent 注释掉,但仍然收到错误,但它移到了另一行。当前第 31 行为:空,第 32 行为:Intent i = getIntent();

标签: java android android-activity nullpointerexception


【解决方案1】:

这是 Main 的第 34 行。 logcat 输出中“Caused by”下的行是相关信息通常所在的位置。

好吧,罪魁祸首应该是初始化器

Intent i = getIntent();
        final String serviceType = i.getStringExtra("serviceType");
        final EditText caller = (EditText) findViewById(R.id.CallerEnter), 
            callExt = (EditText) findViewById(R.id.CallNumberEnter),
            computerName = (EditText) findViewById(R.id.ComputerNameEnter),
            location = (EditText) findViewById(R.id.LocationEnter),
            request = (EditText) findViewById(R.id.RequestEnter);

发生在 Object 构造函数中。由于onClickListener 构造函数将在onCreate() 方法之前运行,getIntent() 将返回 null,并且您不会设置 contentView,因此所有 findViewById() 也将返回 null。

正确的方法是:

private OnClickListener buttonListener = new OnClickListener() {

        ArrayList<NameValuePair> data = new ArrayList<NameValuePair>(5);

        public void onClick(View v) {
                    Intent i = getIntent();
        final String serviceType = i.getStringExtra("serviceType");
        final EditText caller = (EditText) findViewById(R.id.CallerEnter), 
            callExt = (EditText) findViewById(R.id.CallNumberEnter),
            computerName = (EditText) findViewById(R.id.ComputerNameEnter),
            location = (EditText) findViewById(R.id.LocationEnter),
            request = (EditText) findViewById(R.id.RequestEnter);

            Intent intent = new Intent(Main.this, HelpDeskEnd.class);
            final String[] email = {"target emails"};
            data.add(new BasicNameValuePair("Caller: ", textToString(caller)));
            data.add(new BasicNameValuePair("Call Ext: ", textToString(callExt)));
            data.add(new BasicNameValuePair("Computer Name: ", textToString(computerName)));
            data.add(new BasicNameValuePair("Locations: ", textToString(location)));
            data.add(new BasicNameValuePair("Request: ", textToString(request)));
            sendData(data);

            String body = data.get(0).toString() + " " + data.get(1).toString() + " " +
                    data.get(2).toString() + " " + data.get(3).toString() + " " + 
                    data.get(4).toString();
            Mail mail = new Mail("an email", "email password");
            mail.setTo(email);
            mail.setBody(body);
            mail.setFrom("an email");
            mail.setSubject(serviceType);
            try {
                mail.send();
            }
            catch (Exception e) {
                 Log.e("Send Mail", e.getMessage(), e);
            }
            intent.putExtra("serivceType", serviceType);
            startActivity(intent);
        }

    };

【讨论】:

  • 这就是我的想法,第 34 行是:final String serviceType = i.getStringExtra("serviceType"); 如果我将其注释掉并在 onClickListener 中添加一个 serviceType 变量并将其设置为 null,我仍然会遇到相同的错误,但使用 line 36 即:final EditText caller = (EditText) findViewById(R.id.CallerEnter) 我的 R.java 文件有什么问题吗?
  • i 为 null,因为 getIntent() 将返回 null,因为 onClickListeneronCreate() 之前实例化。将getIntent() 和因变量实例化放在onClick()
  • 所有的 findViewById() 也需要移动到 onclick 中。他们不会在他们所在的地方工作。 onCreate() 不会被调用,所以你还没有添加你的 contentView。
  • 非常感谢您的帮助 终于让它工作了,并进一步了解了 onCreate() 的工作原理。
【解决方案2】:

HelpDeskFront.startActivity(intent); 解决问题了吗?

【讨论】:

  • 我假设你的意思是这里? i.putExtra("serviceType", serviceType); startActivity(i); 那只是给我一个错误。不让 porgram 运行
【解决方案3】:

私有 OnClickListener buttonListener = new OnClickListener() {

    public void onClick(View v) {
        String serviceType = null;
        Intent i = new Intent(HelpDeskFront.this, Main.class);
        switch (v.getId()) {
        case R.id.serviceButton :
            serviceType = "service";
            break;
        case R.id.OrderButton :
            serviceType = "order";
            break;
        case R.id.ProgrammingButton :
            serviceType = "programming";
            break;
        }
        i.putExtra("serviceType", serviceType);
        startActivity(i);// change this to startActivityForResult(yourintent,Intent.FILL_IN_DATA)
    }
};

乍一看只是一个想法

【讨论】:

    【解决方案4】:

    尝试像这样使用 if(view==programmingButton)else if(view==another button) 而不是 switch,您能否发布 logcat 并告诉哪些代码(作为 onclick 侦听器或第二个活动的一部分)为空指针异常...

    【讨论】:

      【解决方案5】:

      错误在第 34 行

      final String serviceType = i.getStringExtra("serviceType");
      

      这意味着“i”可能没有正确初始化。

      我会尝试这样做,以便上下文正确。

      Intent i = Main.this.getIntent();
      

      或者您可以像在其他活动中那样创建一个新意图。

      【讨论】:

      • 这修复了我在第 34 行遇到的 NullPointerException,非常感谢!现在我在做同样的事情时遇到了不同的错误。将发布 LogCat 并编辑我所做的代码更改
      【解决方案6】:

      您的应用在其主要活动中的启动方式存在很多问题!

      您需要在 onStart() 方法中而不是在 onCreate() 方法中设置监听器。每次显示活动时并不总是调用 onCreate()。

      您无需使用开关、if/else 或其他任何复杂的方法来找出单击了哪个按钮...每个按钮都有自己的 onClickListener()。在监听器中调用一个私有方法来启动新的活动。

      使用 putExtra() 通过 Intent 传递您想要的任何数据。

      这是一个例子......

      public class MainActivity extends Activity {
      
          @Override
          public void onCreate( final Bundle savedInstanceState ) {
              super.onCreate( savedInstanceState );
              this.setContentView( R.layout.main );
          }
      
          @Override
          protected void onStart() {
              super.onStart();
      
              final Button _serviceButton = (Button)this.findViewById( R.id.buttonService );
              final Button _orderButton = (Button)this.findViewById( R.id.buttonOrder );
              final Button _progButton = (Button)this.findViewById( R.id.buttonProgramming );
      
              _serviceButton.setOnClickListener( new OnClickListener() {
      
                  @Override
                  public void onClick( final View v ) {
                      MainActivity.this.doSomeButtonClick( "service" );
                  }
              } );
      
              _orderButton.setOnClickListener( new OnClickListener() {
      
                  @Override
                  public void onClick( final View v ) {
                      MainActivity.this.doSomeButtonClick( "order" );
                  }
              } );
      
              _progButton.setOnClickListener( new OnClickListener() {
      
                  @Override
                  public void onClick( final View v ) {
                      MainActivity.this.doSomeButtonClick( "programming" );
                  }
              } );
          }
      
          private void doSomeButtonClick( final String type ) {
              final Intent intent = new Intent( MainActivity.this, Activity1.class );
              intent.putExtra( "serviceType", type );
              this.startActivity( intent );
          }
      }
      

      【讨论】:

      • 看我什至不知道存在 OnStart() 方法。我遵循了一个简短的教程,让一些文本出现在屏幕上,然后直接进入这个应用程序。非常感谢;我刚刚学到了很多。我想花一年时间学习 java 不是一个 android 开发者
      • 您在很多方法之前添加了@Override 减速。当我这样做时,我总是会出错。它们那么重要还是我做错了什么?
      • 哈哈是的,整个“Android 方式”很有趣!我没有看,但我简要地注意到您正在发出 HTTP 请求。我强烈建议,如果您还没有这样做,请使用 AsyncTask 并在单独的线程上运行您的请求。
      • @Override 是 Activity 类的重写方法。 developer.android.com/guide/topics/fundamentals/activities.html
      • 顺便说一句-我说的是所有这些,尤其是关于您如何编写意图以及其他什么,因为您当前的错误只是冰山一角!在“纠正”立即的 NullPointerException 后建立 HTTP 连接时,您将遇到更多错误,包括 ANR。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-12
      • 2011-04-07
      • 1970-01-01
      • 2013-10-18
      • 1970-01-01
      • 2017-07-09
      • 1970-01-01
      相关资源
      最近更新 更多