Android:无法启动活动,无法绑定视图

时间:2015-12-13 20:50:19

标签: java android runtime-error weather-api

我正在编写一个Android天气应用程序,但我遇到了一个错误,导致我无法在设备或模拟器上运行它。

以下是我的朋友logcat所说的内容:

Process: com.example.tomfinet.stormy, PID: 9378
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.tomfinet.stormy/com.example.tomfinet.stormy.MainActivity}: java.lang.RuntimeException: Unable to bind views for com.example.tomfinet.stormy.MainActivity
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2358)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2420)
    at android.app.ActivityThread.access$900(ActivityThread.java:154)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5292)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
                                              Caused by: java.lang.RuntimeException: Unable to bind views for com.example.tomfinet.stormy.MainActivity
    at butterknife.ButterKnife.bind(ButterKnife.java:322)
    at butterknife.ButterKnife.bind(ButterKnife.java:237)
    at com.example.tomfinet.stormy.MainActivity.onCreate(MainActivity.java:51)
    at android.app.Activity.performCreate(Activity.java:5990)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2311)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2420) 
    at android.app.ActivityThread.access$900(ActivityThread.java:154) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:135) 
    at android.app.ActivityThread.main(ActivityThread.java:5292) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:372) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699) 
                                              Caused by: java.lang.ClassCastException: android.widget.RelativeLayout cannot be cast to android.widget.TextView
    at com.example.tomfinet.stormy.MainActivity$$ViewBinder.bind(MainActivity$$ViewBinder.java:14)
    at com.example.tomfinet.stormy.MainActivity$$ViewBinder.bind(MainActivity$$ViewBinder.java:8)
    at butterknife.ButterKnife.bind(ButterKnife.java:319)
    at butterknife.ButterKnife.bind(ButterKnife.java:237) 
    at com.example.tomfinet.stormy.MainActivity.onCreate(MainActivity.java:51) 
    at android.app.Activity.performCreate(Activity.java:5990) 
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106) 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2311) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2420) 
    at android.app.ActivityThread.access$900(ActivityThread.java:154) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:135) 
    at android.app.ActivityThread.main(ActivityThread.java:5292) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:372) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699) 
12-13 21:31:50.763 796-2308/? W/ActivityManager:   Force finishing activity 1 com.example.tomfinet.stormy/.MainActivity
12-13 21:31:51.291 796-841/? W/ActivityManager: Activity pause timeout for ActivityRecord{3e556c65 u0 com.example.tomfinet.stormy/.MainActivity t111 f}

以下是MainActivity.java类的内容:

package com.example.tomfinet.stormy;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

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.humidityValue) TextView mHumidityValue;
    @Bind(R.id.precipValue) TextView mPrecipValue;
    @Bind(R.id.summaryLabel) TextView mSummaryLabel;
    @Bind(R.id.iconImageView) ImageView mIconImageView;
    @Bind(R.id.refreshImageView) ImageView mRefreshImageView;
    @Bind(R.id.progressBar) ProgressBar mProgressBar;

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

        // Replaces declaring private member variable and then finding it via id
        ButterKnife.bind(this);

        mProgressBar.setVisibility(View.INVISIBLE);

        final double latitude = 37.8267;
        final double longitude = -122.423;

        mRefreshImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getForecast(latitude, longitude);
            }
        });
    }

    /**
     * Make a simple request and response from to the web
     * @param latitude the angular distance of a place north or south of the earth's equator
     * @param longitude the angular distance of a place east or west of the Greenwich meridian
     */
    private void getForecast(double latitude, double longitude) {
        String apiKey = "93a5479657e625c362ccd931b47debe6";
        String forecastUrl = "https://api.forecast.io/forecast/" + apiKey +
                "/" + latitude + "," + longitude;

        if (networkIsAvailable())
        {
            toggleRefresh();

            OkHttpClient client = new OkHttpClient(); //construct

            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) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            toggleRefresh();
                        }
                    });
                    alertUserAboutError();
                }

                @Override
                public void onResponse(Response response) throws IOException {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            toggleRefresh();
                        }
                    });
                    try {
                        String jsonData = response.body().string(); //stores json data from forecast API
                        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);
                    }
                }
            });
        }
    }

    private void toggleRefresh() {
        if (mProgressBar.getVisibility() == View.INVISIBLE)
        {
            mProgressBar.setVisibility(View.VISIBLE);
            mRefreshImageView.setVisibility(View.INVISIBLE);

        } else
        {
            mProgressBar.setVisibility(View.INVISIBLE);
            mRefreshImageView.setVisibility(View.VISIBLE);
        }
    }

    private void updateDisplay()
    {
        mTemperatureLabel.setText(mCurrentWeather.getTemperature() + "");
        mTimeLabel.setText("At " + mCurrentWeather.getFormattedTime() + "it will be");
        mHumidityValue.setText(mCurrentWeather.getHumidity() + "");
        mPrecipValue.setText(mCurrentWeather.getPrecipChance() + "%");
        mSummaryLabel.setText(mCurrentWeather.getSummary());

        Drawable drawable = getResources().getDrawable(mCurrentWeather.getIconId());
        mIconImageView.setImageDrawable(drawable);
    }

    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("precipChance"));
        currentWeather.setSummary(currently.getString("summary"));
        currentWeather.setTemperature(currently.getDouble("temperature"));
        currentWeather.setTimeZone(timezone);

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

        return currentWeather;
    }

    /**
     * @return true for valid network and connectivity
     */
    private boolean networkIsAvailable()
    {
        ConnectivityManager manager = (ConnectivityManager)
                getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo networkInfo = manager.getActiveNetworkInfo();

        if (networkInfo != null && networkInfo.isConnected())
        {
            return true;
        } else
        {
            Toast.makeText(this, getString(R.string.network_unavailable_message),
                    Toast.LENGTH_LONG).show();
            return false;
        }
    }

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

这是CurrentWeather.java类:

package com.example.tomfinet.stormy;

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

/**
 * Created by tomfinet on 13/12/15.
 */
public class CurrentWeather
{
    private String mIcon;
    private String mSummary;
    private long mTime;
    private double mTemperature;
    private double mHumidity;
    private double mPrecipChance;
    private String mTimeZone;

    public String getTimeZone()
    {
        return mTimeZone;
    }

    public void setTimeZone(String timeZone)
    {
        mTimeZone = timeZone;
    }

    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.mipmap.clear_day;

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

    public String getSummary()
    {
        return mSummary;
    }

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

    public long getTime()
    {
        return mTime;
    }

    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 void setTime(long time)
    {
        mTime = time;
    }

    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 double getPrecipChance() {
        double precipPercentage = mPrecipChance * 100;
        return (int) Math.round(precipPercentage);
    }

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

这是AlertDialogFragment.java类:

package com.example.tomfinet.stormy;

import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;

/**
 * Created by tomfinet on 12/12/15.
 */
public class AlertDialogFragment extends DialogFragment
{
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState)
    {
        Context context = getActivity();
        AlertDialog.Builder builder = new AlertDialog.Builder(context)
                .setTitle(context.getString(R.string.error_title))
                .setMessage(context.getString(R.string.error_message))
                .setPositiveButton(context.getString(R.string.error_ok_button_text), null);

        AlertDialog dialog = builder.create();
        return dialog;
    }
}

如何解决此运行时错误?

感谢您的帮助!

0 个答案:

没有答案
相关问题