How to debug Null Pointer Exception raised by Butt

2019-07-10 20:20发布

I am having another newbie problem. As you can see in my error message. At my MainActivity.java, line 125 is presenting a Null Pointer Exception:

    05-03 22:19:17.559 22615-22615/com.example.andrewjakevillegas.stormy E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.andrewjakevillegas.stormy, PID: 22615
java.lang.
NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at com.example.andrewjakevillegas.stormy.MainActivity.updateDisplay(MainActivity.java:125)
at com.example.andrewjakevillegas.stormy.MainActivity.access$200(MainActivity.java:38)
at com.example.andrewjakevillegas.stormy.MainActivity$1$1.run(MainActivity.java:100)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Here is my MainActivity.java

package com.example.andrewjakevillegas.stormy;

import...    

public class MainActivity extends ActionBarActivity {

    public static final String TAG = MainActivity.class.getSimpleName();

    private CurrentWeather mCurrentWeather;

    @BindView(R.id.timeLabel)
    TextView mTimeLabel;
    @BindView(R.id.temperatureLabel)
    TextView mTemperatureLabel;
    @BindView(R.id.humidityLabel)
    TextView mHumidityValue;
    @BindView(R.id.precipLabel)
    TextView mPrecipValue;
    @BindView(R.id.summaryLabel)
    TextView mSummaryLabel;
    @BindView(R.id.iconImageView)
    ImageView mIconImageView;
    /**
     * ATTENTION: This was auto-generated to implement the App Indexing API.
     * See https://g.co/AppIndexing/AndroidStudio for more information.
     */
    private GoogleApiClient mClient;


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



        if (isNetworkAvailable()) {
            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder()
                    .url( forecastURL )
                    .build();

            Call call = client.newCall( request );
            call.enqueue( new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {

                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {

                    try {
                        String jsonData = response.body().string();
                        Log.v( TAG, jsonData );
                        if (response.isSuccessful()) {
                            mCurrentWeather = getCurrentDetails( jsonData );
                            runOnUiThread( new Runnable() {
                                @Override
                                public void run() {
                                    updateDisplay();
                                }
                            } );
                        } else {
                            alertUserAboutError();
                        }
                    } catch (IOException e) {
                        Log.e( TAG, "Exception caught: ", e );
                    } catch (JSONException e) {
                        Log.e( TAG, "Exception caught: ", e );
                    }
                }
            } );
        } else {
            Toast.makeText( this, getString( R.string.network_unavailable_message ),
                    Toast.LENGTH_LONG ).show();
        }
        Log.d( TAG, "Main UI code is running!" );

        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        mClient = new GoogleApiClient.Builder( this ).addApi( AppIndex.API ).build();
    }

    private void updateDisplay() {
        mTemperatureLabel.setText( mCurrentWeather.getTemperature() + "" );
    }

    private CurrentWeather getCurrentDetails(String jsonData) throws JSONException {
        JSONObject forecast = new JSONObject( jsonData );
        String timezone = forecast.getString( "timezone" );
        Log.i( TAG, "From JSON: " + timezone );

        JSONObject currently = forecast.getJSONObject( "currently" );
        CurrentWeather currentWeather = new CurrentWeather();
        currentWeather.setHumidity( currently.getDouble( "humidity" ) );
        currentWeather.setTime( currently.getLong( "time" ) );
        currentWeather.setIcon( currently.getString( "icon" ) );
        currentWeather.setPrecipChance( currently.getDouble( "precipProbability" ) );
        currentWeather.setSummary( currently.getString( "summary" ) );
        currentWeather.setTemperature( currently.getDouble( "temperature" ) );

        return new CurrentWeather();
    }

    private boolean isNetworkAvailable() {
        ConnectivityManager manager = (ConnectivityManager)
                getSystemService( Context.CONNECTIVITY_SERVICE );
        NetworkInfo networkInfo = manager.getActiveNetworkInfo();
        boolean isAvailable = false;
        if (networkInfo != null && networkInfo.isConnected()) {
            isAvailable = true;
        }

        return isAvailable;
    }

    private void alertUserAboutError() {
        AlertDialogFragment dialog = new AlertDialogFragment();
        dialog.show( getFragmentManager(), "error_dialog" );
    }

    @Override
    public void onStart() {
        super.onStart();

        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        mClient.connect();
        Action viewAction = Action.newAction(
                Action.TYPE_VIEW, // TODO: choose an action type.
                "Main Page", // TODO: Define a title for the content shown.
                // TODO: If you have web page content that matches this app activity's content,
                // make sure this auto-generated web page URL is correct.
                // Otherwise, set the URL to null.
                Uri.parse( "http://host/path" ),
                // TODO: Make sure this auto-generated app URL is correct.
                Uri.parse( "android-app://com.example.andrewjakevillegas.stormy/http/host/path" )
        );
        AppIndex.AppIndexApi.start( mClient, viewAction );
    }

    @Override
    public void onStop() {
        super.onStop();

        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        Action viewAction = Action.newAction(
                Action.TYPE_VIEW, // TODO: choose an action type.
                "Main Page", // TODO: Define a title for the content shown.
                // TODO: If you have web page content that matches this app activity's content,
                // make sure this auto-generated web page URL is correct.
                // Otherwise, set the URL to null.
                Uri.parse( "http://host/path" ),
                // TODO: Make sure this auto-generated app URL is correct.
                Uri.parse( "android-app://com.example.andrewjakevillegas.stormy/http/host/path" )
        );
        AppIndex.AppIndexApi.end( mClient, viewAction );
        mClient.disconnect();
    }
}

This particular line of code is giving me the headache.This is line 125 from my error log.

private void updateDisplay() {
        mTemperatureLabel.setText( mCurrentWeather.getTemperature() + "" );
    }

I have checked my layout. I got the right id and type of TextView.

Here is my activity_main.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:paddingLeft="@dimen/activity_horizontal_margin"
            android:paddingRight="@dimen/activity_horizontal_margin"
            android:paddingTop="@dimen/activity_vertical_margin"
            android:paddingBottom="@dimen/activity_vertical_margin"
            tools:context=".MainActivity"
            android:id="@+id/relativeLayout"
            android:background="#fffc970b">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/temperatureLabel"
    android:layout_centerVertical="true"
    android:layout_centerHorizontal="true"
    android:textColor="@android:color/white"
    android:textSize="150dp"
    android:text="100"/>

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/degreeImageView"
    android:layout_alignTop="@+id/temperatureLabel"
    android:layout_toRightOf="@+id/temperatureLabel"
    android:layout_toEndOf="@+id/temperatureLabel"
    android:layout_marginTop="50dp"
    android:src="@drawable/degree"/>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="At 5:00 PM it will be"
    android:id="@+id/timeLabel"
    android:layout_above="@+id/temperatureLabel"
    android:layout_centerHorizontal="true"
    android:textColor="#95ffffff"
    android:textSize="18sp"/>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Alcatraz Island, CA"
    android:id="@+id/locationLabel"
    android:layout_above="@+id/timeLabel"
    android:layout_centerHorizontal="true"
    android:layout_marginBottom="60dp"
    android:textColor="@android:color/white"
    android:textSize="24sp"/>

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/iconImageView"
    android:layout_alignBottom="@+id/locationLabel"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:src="@drawable/cloudy_night"/>

<LinearLayout
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/temperatureLabel"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="10dp"
    android:weightSum="100"
    android:id="@+id/linearLayout">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_weight="50">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="HUMIDITY"
            android:id="@+id/humidityLabel"
            android:textColor="#95ffffff"
            android:gravity="center_horizontal"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="0.88"
            android:id="@+id/humidityValue"
            android:textColor="@android:color/white"
            android:textSize="24sp"
            android:gravity="center_horizontal"/>
    </LinearLayout>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_weight="50">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="RAIN/SNOW?"
            android:id="@+id/precipLabel"
            android:textColor="#95ffffff"
            android:gravity="center_horizontal"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="100"
            android:id="@+id/precipValue"
            android:textColor="@android:color/white"
            android:textSize="24sp"
            android:gravity="center_horizontal"/>
    </LinearLayout>
</LinearLayout>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Stormy with a chance of meatballs"
    android:id="@+id/summaryLabel"
    android:layout_below="@+id/linearLayout"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="40dp"
    android:textColor="@android:color/white"
    android:textSize="18dp"
    android:gravity="center_horizontal"/>

My Current Weather Java Class should get and set the right values.

public int getTemperature() {
    return (int)Math.round(mTemperature);
}

public void setTemperature(double temperature) {
    mTemperature = temperature;
}

Here is a copy of my CurrentWeather.java just in case you need to refer to it.

    package com.example.andrewjakevillegas.stormy;

public class CurrentWeather {
    private String mIcon;
    private long mTime;
    private double mTemperature;
    private double mHumidity;
    private double mPrecipChance;
    private String mSummary;

    public String getIcon() {
        return mIcon;
    }

    public void setIcon(String icon) {
        mIcon = icon;
    }

    public int getIconId(){
        int iconId = R.drawable.clear_day;

        if (mIcon.equals("clear-day")){
            iconId = R.drawable.clear_day;
        }

        else if (mIcon.equals("clear-night")){
            iconId = R.drawable.clear_night;
        }

        else if (mIcon.equals("rain")) {
            iconId = R.drawable.rain;
        }
        else if (mIcon.equals("snow")) {
            iconId = R.drawable.snow;
        }
        else if (mIcon.equals("sleet")) {
            iconId = R.drawable.sleet;
        }
        else if (mIcon.equals("wind")) {
            iconId = R.drawable.wind;
        }
        else if (mIcon.equals("fog")) {
            iconId = R.drawable.fog;
        }
        else if (mIcon.equals("cloudy")) {
            iconId = R.drawable.cloudy;
        }
        else if (mIcon.equals("partly-cloudy-day")) {
            iconId = R.drawable.partly_cloudy;
        }
        else if (mIcon.equals("partly-cloudy-night")) {
            iconId = R.drawable.cloudy_night;
        }


        return iconId;
    }

    public long getTime() {
        return mTime;
    }

    public void setTime(long time) {
        mTime = time;
    }

    public int getTemperature() {
        return (int)Math.round(mTemperature);
    }

    public void setTemperature(double temperature) {
        mTemperature = temperature;
    }

    public double getHumidity() {
        return mHumidity;
    }

    public void setHumidity(double humidity) {
        mHumidity = humidity;
    }

    public double getPrecipChance() {
        double precipPercentage = mPrecipChance * 100;
        return (int)Math.round(precipPercentage);
    }

    public void setPrecipChance(double precipChance) {
        mPrecipChance = precipChance;
    }

    public String getSummary() {
        return mSummary;
    }

    public void setSummary(String summary) {
        mSummary = summary;
    }


}

Here are the image results when I ran the debugger.

enter image description here

The butterknife is not working from what it looks like. Do you have any suggestions how I can solve this?

4条回答
仙女界的扛把子
2楼-- · 2019-07-10 20:22

Why are you using updateDisplay in a seperate runnable? And then you run this new runnable on the main thread. Seems weird.

anyway, the problem is that your mTemperatureLabel is not initialized. Maybe your bindView operation is not finished when you call the first updateDisplay method.

Edit: As I mentioned in comments, I would not use Butterknife because there are no benefits and you will get problems while debug errors. Anyway, if you wanna use Butterknife no matter what, try Bind instead of BindView.

查看更多
Melony?
3楼-- · 2019-07-10 20:23

I Found the answer to my problem.

You have to download - copy and paste the whole butterknife-compiler (code below)to your build gradle. I was just copying the dependencies and adding it to my gradle dependencies. Which is giving me the problem.

buildscript {
  repositories {
    mavenCentral()
   }
  dependencies {
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
  }
}

apply plugin: 'com.neenbedankt.android-apt'

dependencies {
  compile 'com.jakewharton:butterknife:8.0.1'
  apt 'com.jakewharton:butterknife-compiler:8.0.1'
}
查看更多
4楼-- · 2019-07-10 20:40

In my case i have differents dependencies

First you have similar configuration in yours files build.grade

Problem diferents version [8.0.1 != 8.2.1]

build.gradle(app)

dependencies {
         compile 'com.jakewharton:butterknife:8.2.1'
         apt 'com.jakewharton:butterknife-compiler:8.0.1'
}

i solved using similars versions

dependencies {
         compile 'com.jakewharton:butterknife:8.2.1'
         apt 'com.jakewharton:butterknife-compiler:8.2.1'
}

build.gradle

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.0'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'

    }
}

Good Luck!

查看更多
ら.Afraid
5楼-- · 2019-07-10 20:44
package com.example.com;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;


import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.common.api.GoogleApiClient;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

 import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;

import butterknife.Bind;
import butterknife.ButterKnife;

public class MainActivity extends AppCompatActivity {

public static final String TAG = MainActivity.class.getSimpleName();

private CurrentWeather mCurrentWeather;

@Bind(R.id.timeLabel)
TextView mTimeLabel;
@Bind(R.id.temperatureLabel)
TextView mTemperatureLabel;
@Bind(R.id.humidityLabel)
TextView mHumidityValue;
@Bind(R.id.precipLabel)
TextView mPrecipValue;
@Bind(R.id.summaryLabel)
TextView mSummaryLabel;
[![enter image description here][1]][1]@Bind(R.id.iconImageView)
ImageView mIconImageView;
/**
 * ATTENTION: This was auto-generated to implement the App Indexing API.
 * See https://g.co/AppIndexing/AndroidStudio for more information.
 */
private GoogleApiClient mClient;


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


    String apiKey = "ur_key";
    double latitude = 37.8267;
    double longitude = -122.423;
    String forecastURL = "https://api.forecast.io/forecast/" + apiKey +
            "/" + latitude + "," + longitude;

    if (isNetworkAvailable()) {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url( forecastURL )
                .build();

        Call call = client.newCall( request );
        call.enqueue( new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {

            }

            @Override
            public void onResponse(Response response) throws IOException {

                try {
                    String jsonData = response.body().string();
                    Log.v( TAG, jsonData );
                    if (response.isSuccessful()) {
                        mCurrentWeather = getCurrentDetails( jsonData );
                        runOnUiThread( new Runnable() {
                            @Override
                            public void run() {
                                updateDisplay();
                            }
                        } );
                    } else {
                        alertUserAboutError();
                    }
                } catch (IOException e) {
                    Log.e( TAG, "Exception caught: ", e );
                } catch (JSONException e) {
                    Log.e( TAG, "Exception caught: ", e );
                }
            }
        } );
    } else {
        Toast.makeText( this,  "not available",Toast.LENGTH_SHORT )
               .show();
    }
    Log.d( TAG, "Main UI code is running!" );

    // ATTENTION: This was auto-generated to implement the App Indexing API.
    // See https://g.co/AppIndexing/AndroidStudio for more information.
    mClient = new GoogleApiClient.Builder( this ).addApi( AppIndex.API ).build();
            }


private void updateDisplay() {
    mTemperatureLabel.setText( mCurrentWeather.getTemperature() + "" );
}

private CurrentWeather getCurrentDetails(String jsonData) throws JSONException {
    JSONObject forecast = new JSONObject( jsonData );
    String timezone = forecast.getString( "timezone" );
    Log.i( TAG, "From JSON: " + timezone );

    JSONObject currently = forecast.getJSONObject( "currently" );
    CurrentWeather currentWeather = new CurrentWeather();
    currentWeather.setHumidity( currently.getDouble( "humidity" ) );
    currentWeather.setTime( currently.getLong( "time" ) );
    currentWeather.setIcon( currently.getString( "icon" ) );
    currentWeather.setPrecipChance( currently.getDouble( "precipProbability" ) );
    currentWeather.setSummary( currently.getString( "summary" ) );
    currentWeather.setTemperature( currently.getDouble( "temperature" ) );

    return new CurrentWeather();
}

private boolean isNetworkAvailable() {
    ConnectivityManager manager = (ConnectivityManager)
            getSystemService( Context.CONNECTIVITY_SERVICE );
    NetworkInfo networkInfo = manager.getActiveNetworkInfo();
    boolean isAvailable = false;
    if (networkInfo != null && networkInfo.isConnected()) {
        isAvailable = true;
    }

    return isAvailable;
}

private void alertUserAboutError() {
    AlertDialogFragment dialog = new AlertDialogFragment();
    dialog.show( getFragmentManager(), "error_dialog" );
}

@Override
public void onStart() {
    super.onStart();

    // ATTENTION: This was auto-generated to implement the App Indexing API.
    // See https://g.co/AppIndexing/AndroidStudio for more information.
    mClient.connect();
    Action viewAction = Action.newAction(
            Action.TYPE_VIEW, // TODO: choose an action type.
            "Main Page", // TODO: Define a title for the content shown.
            // TODO: If you have web page content that matches this app activity's content,
            // make sure this auto-generated web page URL is correct.
            // Otherwise, set the URL to null.
            Uri.parse( "http://host/path" ),
            // TODO: Make sure this auto-generated app URL is correct.
            Uri.parse( "android-app://com.example.com/http/host/path" )
    );
    AppIndex.AppIndexApi.start( mClient, viewAction );
}

@Override
public void onStop() {
    super.onStop();

    // ATTENTION: This was auto-generated to implement the App Indexing API.
    // See https://g.co/AppIndexing/AndroidStudio for more information.
    Action viewAction = Action.newAction(
            Action.TYPE_VIEW, // TODO: choose an action type.
            "Main Page", // TODO: Define a title for the content shown.
            // TODO: If you have web page content that matches this app activity's content,
            // make sure this auto-generated web page URL is correct.
            // Otherwise, set the URL to null.
            Uri.parse( "http://host/path" ),
            // TODO: Make sure this auto-generated app URL is correct.
            Uri.parse( "android-app://com.example.andrewjakevillegas.stormy/http/host/path" )
    );
    AppIndex.AppIndexApi.end( mClient, viewAction );
    mClient.disconnect();
}

enter image description here

查看更多
登录 后发表回答