(android)如何发现和解决(NullPointerException)空指针异常问题(持续优化)

大家好,我是豹豹哥,友爱互融,共同进步💕🤞

项目场景:

项目场景:在构建一个APP的过程中没有出现想要的效果(想要点解menu进入SettingActivity.xml的,但是程序老是崩溃,继而成重新运行程序) Logcat出现如下问题:(空指针异常)
  Process: com.example.admin, PID: 6671
    java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.CharSequence android.widget.TextView.getText()' on a null object 


问题描述:

在点击程序右上角的菜单时,程序自动回到SplashActivity.xml界面(后来才知道是程序崩溃的表现)
在这里插入图片描述


原因分析:

根据代码可知,如果程序正常运行,是会跳转到SettingActivity的,但是程序却运行到了SplashActivity,

 case R.id.action_setting:
                Log.d(TAG, "onOptionsItemSelected: action_setting");
                Intent intent = new Intent(MainActivity.this, SettingActivity.class);

然后我在学长的帮助下查阅了整个MainActivity.java发现根本就没有提到SplashActivity(然后得出结论,程序运行到SplashActivity欢迎界面是程序崩溃了,不是其他原因)(崩溃原因自然是上面提到的空指针异常)

package com.example.admin;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

public class MainActivity extends Activity {//to ensure that the MainActivity.java use
    //Activity not ActionBarActivity

    TextView tempView;

    void init() {
        //tempView= findViewById(R.id.text_temp_value);
        tempView = findViewById(R.id.text_temp_value);
    }

    private static final String TAG = "wang";

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {//click oCOM to recreate the method
        getMenuInflater().inflate(R.menu.setting, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
//            case R.id.add_item:
//                Toast.makeText(this, "you clicked Add", Toast.LENGTH_LONG).show();
//                break;
//            case R.id.remove_item:
//                Toast.makeText(this,"you clicked Remove",Toast.LENGTH_LONG).show();
//                break;
            case R.id.action_setting:
                Log.d(TAG, "onOptionsItemSelected: action_setting");
                Intent intent = new Intent(MainActivity.this, SettingActivity.class);
                //to get the value of temperature


                Log.d(TAG, "onOptionsItemSelected: tempview is " + (tempView == null));

                if (tempView == null) {
                    Log.d(TAG, "onOptionsItemSelected: is null");
                } else {


                    Log.d(TAG, "onOptionsItemSelected: is not null");
                }

//                String tempValue = tempView.getText().toString().trim();

                String tempValue = getStr(tempView);

                Log.d(TAG, "onOptionsItemSelected: 11111");

                Log.d(TAG, "onOptionsItemSelected: the tempValue is " + tempValue);
                intent.putExtra("tempValue", tempValue);
                Log.d(TAG, "onOptionsItemSelected: put in.");
                startActivity(intent);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

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

    }

    public String getStr(TextView tx) {
        return tx.getText().toString().trim();
    }

}


解决方案:

(在学长帮助下解决了问题,为了叙述方便,下面用第一人称)

这里隆重介绍查错必备,log家族,有关log查错的文章可以看其他博主的)代码看上面的一大长串的就好。

步骤一:

首先:(用Logd写一句打印语句,判断有没有获得action_setting的ID)(结果是成立)

  case R.id.action_setting:
                Log.d(TAG, "onOptionsItemSelected: action_setting");
                Intent intent = new Intent(MainActivity.this, SettingActivity.class);

然后再这个地方用了打印语句,发现打印不出来(那问题就出现在这两句直之间了)

   intent.putExtra("tempValue",tempValue);
                Log.d(TAG, "onOptionsItemSelected: put in.");
                startActivity(intent);
                return true;

步骤二:

继续缩小范围

String tempValue = tempView.getText().toString().trim();

//                String tempValue = getStr(tempView);

                Log.d(TAG, "onOptionsItemSelected: 11111");

                Log.d(TAG, "onOptionsItemSelected: the tempValue is "+tempValue);
                intent.putExtra("tempValue",tempValue);

发现还是打印不出来,然后问题就明确了,这段代码的上面只有一条语句

  String tempValue = tempView.getText().toString().trim();

这就是问题所在了

步骤三:

到这里只是知道问题在哪里,但是具体原因还不清楚,然后我们用更细化的打印语句结合if来找出具体是哪个空指针

 Log.d(TAG, "onOptionsItemSelected: tempview is "+(tempView==null));
                if (tempView==null){
                    Log.d(TAG, "onOptionsItemSelected: is null");
                }else {
                    Log.d(TAG, "onOptionsItemSelected: is not null");
                }

(上面这段代码用来看是不是出现了空指针异常)

  Log.d(TAG, "onOptionsItemSelected: 11111");

                Log.d(TAG, "onOptionsItemSelected: the tempValue is "+tempValue);

(上面这段代码用来判断是tempView为空指针还是tempValue为空指针)
根据logcat打印语句,发现是tempView为空指针

(下面这段代码中是把text_temp_value绑定给tempView的,但是结合再下面一段代码我们发现一个致命问题)

 void init(){
        //tempView= findViewById(R.id.text_temp_value);
        tempView= findViewById(R.id.text_temp_value);
    }

(注意setContentView(R.id.activity_main)方法,所以我们的text_temp_value理应出现再activity_main里啊,但是在activity_main里查不到(请看再下面一张图片))

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

在这里插入图片描述

步骤四:

OK,所有的问题都发现了,下面我们改了一下传递的id,成功运行!

 void init(){
        //tempView= findViewById(R.id.text_temp_value);
        tempView= findViewById(R.id.real_time_temperature);
    }
<TextView
            android:id="@+id/real_time_temperature"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:background="@color/white_blue_green"
            android:text="@string/real_time_temperature"
            android:textColor="@color/red" />

结语:通过这段博客的书写,我发现我对于空指针异常这个地方理解的还不够深入,希望大家多多评论和私信,如有不足,还望指正😘🤞

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

豹豹-Boss成

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值