我还有另一个新手问题。正如您在我的错误消息中看到的那样。在我的MainActivity.java中,第125行显示空指针异常:
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)
这是我的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();
}
}
这段特殊代码令我头痛。这是我的错误日志中的第125行。
private void updateDisplay() {
mTemperatureLabel.setText( mCurrentWeather.getTemperature() + "" );
}
我检查了我的布局。我得到了正确的文本视图ID和类型。
这是我的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应该获取并设置正确的值。
public int getTemperature() {
return (int)Math.round(mTemperature);
}
public void setTemperature(double temperature) {
mTemperature = temperature;
}
以下是我的CurrentWeather.java的副本,以防你需要引用它。
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;
}
}
以下是运行调试器时的图像结果。
奶油刀的样子不起作用。您有什么建议我可以解决这个问题吗?
答案 0 :(得分:3)
我找到了问题的答案。
您必须下载 - 将整个butterknife编译器(下面的代码)复制并粘贴到您的构建gradle中。我只是复制依赖项并将其添加到我的gradle依赖项中。这给了我这个问题。
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'
}
答案 1 :(得分:0)
为什么在单独的runnable中使用updateDisplay?然后在主线程上运行这个新的runnable。看起来很奇怪。
无论如何,问题是你的mTemperatureLabel没有被初始化。调用第一个updateDisplay方法时,可能没有完成bindView操作。
编辑:正如我在评论中提到的,我不会使用Butterknife,因为没有任何好处,你会在调试错误时遇到问题。无论如何,如果你想使用Butterknife无论如何,试试Bind而不是BindView。
答案 2 :(得分:0)
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();
}
答案 3 :(得分:0)
在我的情况下,我有不同的依赖
首先,你的文件build.grade
中有类似的配置问题差异版本[8.0.1!= 8.2.1]
的build.gradle(应用的)
dependencies {
compile 'com.jakewharton:butterknife:8.2.1'
apt 'com.jakewharton:butterknife-compiler:8.0.1'
}
我使用类似版本解决了
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'
}
}
祝你好运!