-4

Currently, I am getting trouble of passing data to the interface, because of

 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at com.example.miaor.stormyprofessional.UI.MainActivity$override.updateDisplay(MainActivity.java:112)
at com.example.miaor.stormyprofessional.UI.MainActivity$override.static$access$200(MainActivity.java:32)
at com.example.miaor.stormyprofessional.UI.MainActivity$override.access$dispatch(MainActivity.java)
at com.example.miaor.stormyprofessional.UI.MainActivity.access$200(MainActivity.java:0)
at com.example.miaor.stormyprofessional.UI.MainActivity$1$1$override.run(MainActivity.java:89)
at com.example.miaor.stormyprofessional.UI.MainActivity$1$1$override.access$dispatch(MainActivity.java)
at com.example.miaor.stormyprofessional.UI.MainActivity$1$1.run(MainActivity.java:0)
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)

The thing is, I know this mainly caused by messing up with layout ID, so I checked it and everything is fine. Right now, I have no idea what I do wrong.

Here is the relevant code in MainActivity

    private Current mCurrent;

@BindView(R.id.iconImage) ImageView mIconImage;
@BindView(R.id.SummaryText) TextView mSummaryText;
@BindView(R.id.temperatureValue) TextView mTemperatureValue;
@BindView(R.id.humidityValue) TextView mHumidityValue;
@BindView(R.id.PrecipChanceValue) TextView mPrecipChanceValue;
@BindView(R.id.timeValue) TextView mTimeValue;



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

    if (NetworkIsAvailable()) {
        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) {
                Log.e(TAG, "failure");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                try{
                    String jsonData = response.body().string();
                    Log.v(TAG, jsonData);
                    if (response.isSuccessful()){
                        mCurrent = getCurrentWeather(jsonData);
                        Log.i(TAG, mCurrent.getIconID()
                                + "," + mCurrent.getHumidity()
                                + "," + mCurrent.getTemperature()
                                + "," + mCurrent.getPrecipProbability()
                                + "," + mCurrent.getSummary()
                                + "," + mCurrent.getFormattedTime());

                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                updateDisplay();

                            }
                        });
                    }
                    else {
                        ErrorMessage();
                    }
                }
                catch (IOException | JSONException e){
                    Log.e(TAG, "Exception caught", e);
                }
            }
        });
    }
    else {
        Toast.makeText(this, R.string.deadNetwork,
                Toast.LENGTH_LONG).show();
    }
}

private void updateDisplay() {
    mTemperatureValue.setText(mCurrent.getTemperature()+"");
    mHumidityValue.setText(mCurrent.getHumidity()+"%");
    mPrecipChanceValue.setText(mCurrent.getPrecipProbability()+"%");
    mSummaryText.setText(mCurrent.getSummary());
    mTimeValue.setText(mCurrent.getFormattedTime());
    mIconImage.setImageDrawable(getResources().getDrawable(mCurrent.getIconID()));
}

And my activity_main.xml file down below

<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"
tools:context=".UI.MainActivity"
android:background="@color/colorPrimaryDark">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="000"
    android:id="@+id/temperatureValue"
    android:layout_centerVertical="true"
    android:layout_centerHorizontal="true"
    android:textSize="100sp"
    android:textColor="@color/textColor"/>

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/DegreeImage"
    android:layout_alignTop="@+id/temperatureValue"
    android:layout_toRightOf="@+id/temperatureValue"
    android:layout_toEndOf="@+id/temperatureValue"
    android:src="@drawable/degree"/>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="0:00 AM"
    android:id="@+id/timeValue"
    android:layout_above="@+id/temperatureValue"
    android:layout_centerHorizontal="true"
    android:textSize="20sp"
    android:textColor="@color/textColor"
    android:layout_marginBottom="30dp"/>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/zhangjiagang_cn"
    android:id="@+id/LocationText"
    android:layout_above="@+id/timeValue"
    android:layout_centerHorizontal="true"
    android:textSize="30sp"
    android:textColor="@color/textColor"
    android:layout_marginBottom="80dp"/>

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/iconImage"
    android:layout_alignTop="@+id/temperatureValue"
    android:layout_toLeftOf="@+id/temperatureValue"
    android:layout_toStartOf="@+id/temperatureValue"
    android:src="@drawable/sunny"/>

<LinearLayout
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingRight="30dp"
    android:paddingLeft="30dp"
    android:layout_below="@+id/temperatureValue"
    android:layout_centerHorizontal="true"
    android:baselineAligned="false"
    android:id="@+id/linearLayout">

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

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/humidity"
            android:id="@+id/HumidityText"
            android:layout_gravity="center"
            android:gravity="center"
            android:textSize="20sp"
            android:textColor="@color/textColor"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="000%"
            android:id="@+id/humidityValue"
            android:gravity="center"
            android:textSize="20sp"
            android:textColor="@color/textColor"/>
    </LinearLayout>

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

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/rain_snow"
            android:id="@+id/PrecipChanceText"
            android:layout_gravity="center"
            android:gravity="center"
            android:textSize="20sp"
            android:textColor="@color/textColor"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="000%"
            android:id="@+id/PrecipChanceValue"
            android:textSize="20sp"
            android:textColor="@color/textColor"
            android:gravity="center"/>
    </LinearLayout>
</LinearLayout>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="blahblahblahblah"
    android:layout_marginTop="40dp"
    android:textSize="18sp"
    android:textColor="@color/textColor"
    android:id="@+id/SummaryText"
    android:layout_below="@+id/linearLayout"
    android:layout_centerHorizontal="true"/>

I just made another approach. Instead of using butterKnife, I used the normal way to bind the TextView and It still give me the same error.

Here is the example of my code

 private Current mCurrent;
private TextView mTemperatureValue;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main)
    TextView mTemperatureValue = (TextView)findViewById(R.id.temperatureValue);

Everything besides of this is the same, and for those who wants to check the whole code, here is my project in github https://github.com/ohmyskyhigh/StormyProfessional

Runkun Miao
  • 335
  • 1
  • 3
  • 14
  • Your ``TextView`` object seems to be null. – f1sh Jul 08 '16 at 10:03
  • 3
    Bro, please post the relevant code (MainActivity) here, rather than link to the github project. Not many people will want to waste their time searching for it in the github folder structure. As far as I can see, you've not used ButterKnife well, your textview is null when you're trying to access it. – Vucko Jul 08 '16 at 10:04
  • Does ButterKnife show any errors when binding? Definitely the cause is that the `TextView` variable doesn't get bound to the view. – Thorsten Dittmar Jul 08 '16 at 10:30
  • @ThorstenDittmar if binding problem happened then its gives binding error not NPE. – sushildlh Jul 08 '16 at 10:32
  • 1
    @sushildlh Doesn't matter. Fact: `TextView` variable is `null`. Could also be caused by the thread starting to run before the assignment is made. Going to change my answer. – Thorsten Dittmar Jul 08 '16 at 10:36
  • @ThorstenDittmar have look on butterknife NPE http://stackoverflow.com/questions/23076103/using-butter-knife-library-for-view-injection – sushildlh Jul 08 '16 at 10:37
  • @sushildlh I've worked with ButterKnife before, but never had binding issues. Still, my answer is the same: His code accesses `TextView` member variables that have either not been bound at all or before binding succeeds. That's why they are `null` and that's why he's getting this error. – Thorsten Dittmar Jul 08 '16 at 10:41
  • @Runkun Miao did you get the Log.i() values in your logcat ?? – sushildlh Jul 08 '16 at 10:46
  • @sushildlh, yes and everything alright, – Runkun Miao Jul 08 '16 at 10:50
  • have you tried my answer for removing thread ?? – sushildlh Jul 08 '16 at 10:52

3 Answers3

1

Now that you've posted some code it is obvious that you're using ButterKnife, so manual binding is not necessary.

Could be one of the following problems:

  1. You're just declaring the variable, but you're not calling findViewById to get an actual instance. => You need to somewhere call findViewById before you can use the instance variable for the text box.
  2. You're calling findViewById to get the reference to your text box in code, but it returns null as no view with the given ID is found => check whether the IDs are alright, set a breakpoint on that line to check whether the respective call returns null.

Could also be that you've changed the IDs but the project didn't get recompiled. Try a clean build to check.

I see from your code now that you're using a thread for UI updates. Maybe the thread starts running while member variables are still unbound. You could try changing your update method like this:

private void updateDisplay() {
    if (mTemperatureValue != null)
        mTemperatureValue.setText(mCurrent.getTemperature()+"");
    if (mHumidityValue != null) 
        mHumidityValue.setText(mCurrent.getHumidity()+"%");
    if (mPrecipChanceValue != null)
        mPrecipChanceValue.setText(mCurrent.getPrecipProbability()+"%");
    if (mSummaryText != null)
        mSummaryText.setText(mCurrent.getSummary());
    if (mTimeValue != null)
        mTimeValue.setText(mCurrent.getFormattedTime());
    mIconImage.setImageDrawable(getResources().getDrawable(mCurrent.getIconID()));
}

If you after that change see that at some point you're getting values in the text boxes, then this was the problem.

If you not see any values then the text boxes are not being properly bound by ButterKnife.

Thorsten Dittmar
  • 55,956
  • 8
  • 91
  • 139
  • From, from butterKnife docs, I didn't see the necessity of using [findViewByID], and from my use of butterKnife, I've never used[findViewByID]. Besides, I really don't know where to put that code. – Runkun Miao Jul 08 '16 at 10:45
  • You didn't say you used ButterKnife when I wrote this answer, as you hadn't posted any code. Of course, when using ButterKnife you don't need to find your views manually. Still, try the last edit to see what happens. I guess it's a threading problem. – Thorsten Dittmar Jul 08 '16 at 10:46
  • And on a side note: I think that before using any frameworks like ButterKnife it's a good idea to know how things work. If you had this knowledge it would be clear where to put the calls to `findViewById` :-) – Thorsten Dittmar Jul 08 '16 at 10:49
  • I've tried your method and gives me the default screen, well, at least I know all my views haven't bind to the mainActivity – Runkun Miao Jul 08 '16 at 11:03
  • @RunkunMiao So now you can start to look at why this is happening. For example: Are the members bound right after the call to ButterKnife? Set breakpoints and debug! – Thorsten Dittmar Jul 08 '16 at 11:06
  • @RunkunMiao Would be interesting to know what the exact cause was. – Thorsten Dittmar Jul 15 '16 at 11:40
0

One thing where this also happens is when you change the XML .. most of the times you have to do Project->Clean then and try again and it works.

Michele La Ferla
  • 6,775
  • 11
  • 53
  • 79
-3

Before setText check those text you want to set its !null if its null then produce null object reference other wise use like this

tv.setText(""+ here you want to set);
Nitesh Pareek
  • 362
  • 2
  • 10