一切正常,直到我使用 updateDisplay 方法,导致应用程序崩溃

Everything works until I use updateDisplay method, causing the app to crash

在我用代码填充 updateDisplay() 方法以使用 setText/get 更新我的 textViews 之前,一切都正确显示在屏幕上。

应用程序在输入 setText/get 代码以从 DarkSky API 更新之前不会崩溃,但一旦输入,应用程序就会崩溃并告诉我重试。

我相信输入的所有内容都是正确的,但由于某种原因,该应用程序不会获取信息。另外,我在 cradle 中使用最新版本的 OkHTTP,所以问题不在于此。 (也使用权限)

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

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

import java.io.IOException;

import butterknife.BindView;
import butterknife.ButterKnife;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity {

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

private CurrentWeather mCurrentWeather;

@BindView(R.id.timeLabel) TextView mTimeLabel;
@BindView(R.id.tempLabel) TextView mTempLabel;
@BindView(R.id.humidityValue) TextView mHumidityValue;
@BindView(R.id.precipValue) TextView mPrecipValue;
@BindView(R.id.summaryLabel) TextView mSummaryLabel;
@BindView(R.id.iconImageView) ImageView mIconImageView;

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

    String apiKey = "MY KEY";
    double latitude = 37.8267;
    double longitude = -122.4233;
    String forecastURL = ("https://api.darksky.net/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(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 | JSONException e) {
                    Log.e(TAG, "Exception caught: ", e);
                }
            }
        });
    }

    else {
        Toast.makeText(this, R.string.network_unavailable_message,
                Toast.LENGTH_LONG).show(); // CHALLENGE: Turn into dialog
    }
    Log.d(TAG, "Main UI code is running!");
}

private void updateDisplay() {
    mSummaryLabel.setText(mCurrentWeather.getSummary());
    mTempLabel.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.getInt("temperature"));
    currentWeather.setTimeZone(timezone);

    Log.d(TAG, currentWeather.getFormattedTime());

    return 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");
}
}

包 tricksterantics.com.catsndogs;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

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


public String getTimeZone() {
    return mTimeZone;
}

public void setTimeZone(String timeZone) {

    mTimeZone = timeZone;
}

private String mTimeZone;

public String getIcon() {

    return mIcon;
}


public void setIcon(String icon) {

    mIcon = icon;
}

public int getIconId() {
    // clear-day, clear-night, rain, snow, sleet, wind, fog, cloudy, partly-cloudy-day, or partly-cloudy-night.
    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 String getFormattedTime () {
    SimpleDateFormat formatter = new SimpleDateFormat("h:mm a");
    formatter.setTimeZone(TimeZone.getTimeZone(getTimeZone()));
    Date dateTime = new Date(getTime() * 1000);
    String timeString = formatter.format(dateTime);

    return timeString;
}

public double 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 int 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;
}

}

编辑: 添加了堆栈跟踪的图像 Stack trace

摆脱了我使用的 Butterknife 格式 (BindVIew) 并选择了这个,现在一切正常并且正在从 API 检索更新的信息:

public class MainActivity 扩展 AppCompatActivity {

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

private CurrentWeather mCurrentWeather;

private TextView mTimeLabel;

private TextView mTempLabel;

private TextView mHumidityValue;

private TextView mPrecipValue;

private TextView mSummaryLabel;

private ImageView mIconImageView;



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

    mTimeLabel = (TextView) findViewById(R.id.timeLabel);
    mTempLabel = (TextView) findViewById(R.id.tempLabel);
    mHumidityValue = (TextView) findViewById(R.id.humidityValue);
    mPrecipValue = (TextView) findViewById(R.id.precipValue);
    mSummaryLabel = (TextView) findViewById(R.id.summaryLabel);