新人第一篇博客

标签: Android  Studio  Butterknife  null pointer  exception

前言

最近在自学Android,由于没有人指导,也只能跟着书上的范例或者网上的例子来敲代码,中间一些自己的理解或者感悟,总是过了就是过去了,之后再想起肯定没有那么深的记忆了,所以开始写写博客,希望能把自己犯的错和自己的理解记下,同时也希望能通过这个平台与各位大佬沟通交流。本次第一篇博客写的是自己平常遇到的一些空指针异常。

布局文件未绑定引起的空指针异常

这个在刚开始写Android程序很常见了,大部分是因为没有把布局文件(也就是那些layout文件夹里的activity_xxxx.xml或者fragment_xxxx.xml文件里的一些控件,如button,textview等等)与逻辑操作文件(java文件夹里的XxxxActivity.java或者XxxxFragment.java)给绑定起来,在运行模拟器时,由于没有将布局文件里的控件与逻辑操作文件绑定起来,导致系统找不到该控件,因此报错。

下例演示了一个非常简单的空指针异常问题

布局文件activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.a16832.myapplication.MainActivity">


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


    <Button
        android:id="@+id/btn_1"
        android:text="测试空指针异常"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />


</LinearLayout>

在这个初建的文件里,我没有删除hello world的textview,虽然它其实也不妨碍什么,但是这个不是那什么,第一篇博客嘛,我也强行来一个hello world!然后其次是比较新的Android Studio版本中,默认使用的界面布局,我也不知道叫什么,它使用的是ConstraintLayout,这种布局我不知道有什么好处,让它成为了默认的布局,可能下一篇博客就是介绍这两种布局的不同。这里我改成了LinearLayout线性布局,然后记得把orientation方向设置成vertical垂直的。

逻辑操作文件MainActivity.java文件

package com.example.a16832.myapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;


public class MainActivity extends AppCompatActivity {
    public Button btn_1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//        btn_1=(Button)findViewById(R.id.btn_1); //这里把btn_1的绑定操作给注释掉了,只为做一个对比
        btn_1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this,"按键1被按下",Toast.LENGTH_SHORT).show();
            }
        });
    }
}

如上面所示,我只是定义了一个button的功能,而把绑定的那一句给注释掉了

然后看模拟器的运行,这里在我使用genymotion模拟器时出了个问题,是AS没有检测到我的模拟器, 在之后的博客里再说。

由于我这里没有将btn_1与逻辑操作文件绑定起来,在正式运行时,直接出现了如下图的报错


这里的第18行的代码如下

btn_1.setOnClickListener(this);

为什么这里会出现空指针异常呢,是因为我们在上面btn_1绑定的时候把这一句注释掉了,我把

        btn_1=(Button)findViewById(R.id.btn_1); //这里把btn_1的绑定操作给注释掉了,只为做一个对比

这一句的双斜杠去掉后,这个程序就完全正常运行了


介绍一款神器Butterknife

butterknife是一款将布局文件与逻辑操作文件自动绑定管理的插件,功能非常强大,也很方便,为了测试这个神器的功能,我这次将布局文件加了很多控件。如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.a16832.myapplication.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_1"
        android:text="测试空指针异常1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/btn_2"
        android:text="测试空指针异常2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/btn_3"
        android:text="测试空指针异常3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/btn_4"
        android:text="测试空指针异常4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/btn_5"
        android:text="测试空指针异常5"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/btn_6"
        android:text="测试空指针异常6"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/tv_2"
        android:text="thank you all to watch this blog"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />


</LinearLayout>

而逻辑文件则还原成最开始的状态如下:

package com.example.a16832.myapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}
是不是感觉要把这些布局控件添加到逻辑文件里的工作量很大呢?这里我们使用Butterknife来完成这一操作。首先是在File->setting->plugins里搜索butterknife,如图:


这里没有安装过的,得点击下方三个选项里中间那个Browse repositories,然后安装并重启,然后我们打开File->File Structure,或者点下面这个图标,图标在右边的是因为没有打开toolbar(点击View,然后勾中toolbar,建议打开)



然后点击右上角的加号,选择第一个Library dependency,然后再搜索框中搜索butterknife,然后双击或者点击OK


然后我们回到我们的MainActivity.java里,这时候点到我们的布局文件,右键,里面有一个generate,然后出现generate butterknife injection,这时候点击就会自动帮我们把布局文件里的控件与逻辑文件绑定起来




这里会出现我之前在xml文件里分配了id的控件,其中里面的button和textv都可以设置点击事件。点击confirm就可以把所有的控件与逻辑操作绑定啦。完美!

package com.example.a16832.myapplication;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class MainActivity extends AppCompatActivity {
    @BindView(R.id.btn_1)
    Button btn1;
    @BindView(R.id.btn_2)
    Button btn2;
    @BindView(R.id.btn_3)
    Button btn3;
    @BindView(R.id.btn_4)
    Button btn4;
    @BindView(R.id.btn_5)
    Button btn5;
    @BindView(R.id.btn_6)
    Button btn6;
    @BindView(R.id.tv_2)
    TextView tv2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
    }

    @OnClick({R.id.btn_1, R.id.btn_2, R.id.btn_3, R.id.btn_4, R.id.btn_5, R.id.btn_6})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.btn_1:
                break;
            case R.id.btn_2:
                break;
            case R.id.btn_3:
                break;
            case R.id.btn_4:
                break;
            case R.id.btn_5:
                break;
            case R.id.btn_6:
                break;
        }
    }
}
第一篇博客为什么写空指针异常呢,这个空指针异常问题其实是我java基础不牢固的原因,但之前是看不下去,而在看到AS可以很快的生成一个可以运行的app,于是就有点开始没学会走就想跑了,但是这个终归是把我的兴趣给往这上面引了,有了这个兴趣,我才会去看以前不愿意看或者说懒得看的一些比较基础的知识了!


版权声明:本文为blessedbliss原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/blessedbliss/article/details/80896840