ServiceSuccess方法失败?

时间:2016-07-18 23:24:04

标签: java android methods

我正在创建一个应用程序,它在打开时崩溃了。堆栈跟踪提到了为天气代码设置drawable的问题? 这是......

Process: com.oxinc.android.drate, PID: 22629
                                                                     java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setImageDrawable(android.graphics.drawable.Drawable)' on a null object reference
                                                                         at com.oxinc.android.drate.MainActivity.serviceSuccess(MainActivity.java:243)
                                                                         at com.oxinc.android.drate.service.YahooWeatherService$1.onPostExecute(YahooWeatherService.java:93)
                                                                         at com.oxinc.android.drate.service.YahooWeatherService$1.onPostExecute(YahooWeatherService.java:35)
                                                                         at android.os.AsyncTask.finish(AsyncTask.java:651)
                                                                         at android.os.AsyncTask.-wrap1(AsyncTask.java)
                                                                         at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
                                                                         at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                         at android.os.Looper.loop(Looper.java:148)
                                                                         at android.app.ActivityThread.main(ActivityThread.java:5456)
                                                                         at java.lang.reflect.Method.invoke(Native Method)
                                                                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
                                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)

这是MainActivity.java

package com.oxinc.android.drate;

import android.app.Activity;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;

import android.support.v7.app.AppCompatActivity;

import android.Manifest;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.preference.PreferenceManager;
import android.support.design.widget.TabLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.oxinc.android.drate.data.Channel;
import com.oxinc.android.drate.data.Condition;
import com.oxinc.android.drate.data.LocationResult;
import com.oxinc.android.drate.fragments.SettingsFragment;
import com.oxinc.android.drate.listener.GeocodingServiceListener;
import com.oxinc.android.drate.listener.WeatherServiceListener;
import com.oxinc.android.drate.service.GoogleMapsGeocodingService;
import com.oxinc.android.drate.service.WeatherCacheService;
import com.oxinc.android.drate.service.YahooWeatherService;


public class MainActivity extends AppCompatActivity implements WeatherServiceListener, GeocodingServiceListener, LocationListener {

    private ImageView weatherIconImageView;
    private TextView temperatureTextView;
    private TextView conditionTextView;
    private TextView locationTextView;
    private YahooWeatherService weatherService;
    private GoogleMapsGeocodingService geocodingService;
    private WeatherCacheService cacheService;
    private ProgressDialog dialog;


//Other Variables
    private void startSettingsActivity() {
        Intent intent = new Intent(this, SettingsActivity.class);
        startActivity(intent);
    }


    /**
     * The {@link android.support.v4.view.PagerAdapter} that will provide
     * fragments for each of the sections. We use a
     * {@link FragmentPagerAdapter} derivative, which will keep every
     * loaded fragment in memory. If this becomes too memory intensive, it
     * may be best to switch to a
     * {@link android.support.v4.app.FragmentStatePagerAdapter}.
     */
    private SectionsPagerAdapter mSectionsPagerAdapter;

    /**
     * The {@link ViewPager} that will host the section contents.
     */
    private ViewPager mViewPager;

    //Weather Implemented//


    // weather service fail flag
    public boolean weatherServicesHasFailed = false;

    public SharedPreferences preferences = null;


    //OnCreate Method

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

        weatherIconImageView = (ImageView) findViewById(R.id.weatherIconImageView);
        temperatureTextView = (TextView) findViewById(R.id.temperatureTextView);
        conditionTextView = (TextView) findViewById(R.id.conditionTextView);
        locationTextView = (TextView) findViewById(R.id.locationTextView);

//        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
//        setSupportActionBar(toolbar);
        // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.container);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        //Tabbed Layout
        TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(mViewPager);

        //Floating Action Button
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startSettingsActivity();
            }
        });

        preferences = PreferenceManager.getDefaultSharedPreferences(this);

        weatherService = new YahooWeatherService(this);
        weatherService.setTemperatureUnit(preferences.getString(getString(R.string.pref_temperature_unit), null));

        geocodingService = new GoogleMapsGeocodingService(this);
        cacheService = new WeatherCacheService(this);


        if (preferences.getBoolean(getString(R.string.pref_needs_setup), true)) {
            startSettingsActivity();
        } else {

            dialog = new ProgressDialog(this);
            dialog.setMessage(getString(R.string.loading));
            dialog.setCancelable(true);
            dialog.show();

            String location = null;

            if (preferences.getBoolean(getString(R.string.pref_geolocation_enabled), true)) {
                String locationCache = preferences.getString(getString(R.string.pref_cached_location), null);

                if (locationCache == null) {
                    getWeatherFromCurrentLocation();
                } else {
                    location = locationCache;
                }
            } else {
                location = preferences.getString(getString(R.string.pref_manual_location), null);
            }

            if (location != null) {
                weatherService.refreshWeather(location);
            }
        }

    }

    private void getWeatherFromCurrentLocation() {
        // system's LocationManager
        LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

        // medium accuracy for weather, good for 100 - 500 meters
        Criteria locationCriteria = new Criteria();
        locationCriteria.setAccuracy(Criteria.ACCURACY_FINE);

        String provider = locationManager.getBestProvider(locationCriteria, true);

        // single location update
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        locationManager.requestSingleUpdate(provider, this, null);
    }




    @Override
    public void serviceSuccess(Channel channel) {

        dialog.hide();

        Condition condition = channel.getItem().getCondition();

        int resourceId = getResources().getIdentifier("drawable/icon_" + condition.getCode(), null, getPackageName());

        @SuppressWarnings("deprecation")
        Drawable weatherIconDrawable = getResources().getDrawable(resourceId);

        weatherIconImageView.setImageDrawable(weatherIconDrawable);

        String temperatureLabel = getString(R.string.temperature_output, condition.getTemperature(), channel.getUnits().getTemperature());

        temperatureTextView.setText(temperatureLabel);
        conditionTextView.setText(condition.getDescription());
        locationTextView.setText(channel.getLocation());
    }

    @Override
    public void serviceFailure(Exception exception) {
        // display error if this is the second failure
        if (weatherServicesHasFailed) {
            dialog.hide();
            Toast.makeText(this, exception.getMessage(), Toast.LENGTH_LONG).show();
        }
        else {
            // error doing reverse geocoding, load weather data from cache
            weatherServicesHasFailed = true;
            // OPTIONAL: let the user know an error has occurred then fallback to the cached data
            Toast.makeText(this, exception.getMessage(), Toast.LENGTH_SHORT).show();

            cacheService.load(this);
        }
    }

    @Override
    public void geocodeSuccess(LocationResult location) {
        // completed geo coding successfully
        weatherService.refreshWeather(location.getAddress());

        SharedPreferences.Editor editor = preferences.edit();
        editor.putString(getString(R.string.pref_cached_location), location.getAddress());
        editor.apply();
    }

    @Override
    public void geocodeFailure(Exception exception) {
        // GeoCoding failed, try loading weather data from the cache
        cacheService.load(this);
    }

    @Override
    public void onLocationChanged(Location location) {
        geocodingService.refreshLocation(location);
    }

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {
        // OPTIONAL: implement your custom logic here
    }

    @Override
    public void onProviderEnabled(String s) {
        // OPTIONAL: implement your custom logic here
    }

    @Override
    public void onProviderDisabled(String s) {
        // OPTIONAL: implement your custom logic here
    }

//On Create

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main_menu, menu);
        return true;
    }



    /**
     * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
     * one of the sections/tabs/pages.
     */
    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public int getCount() {
            // Show 3 total pages.
            return 3;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            switch (position) {
                case 0:
                    return "Hydration";
                case 1:
                    return "Weigh In";
                case 2:
                    return "Weather";
            }
            return null;
        }


        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    return new Hydration();
                case 1:
                    return new Weight();
                case 2:
                    return new Weather();
                default:
                    // this should never happen
                    return null;
                //return new Fragment();
            }
        }
    }



        public int quantity = 0;
        public String outcome = "";
        public int required = 0;
        public int height = 0;

    public void eight(View view) {
        quantity = quantity + 8;
        displayQuantity(quantity);
    }

    public void twelve(View view) {
        quantity = quantity + 12;
        displayQuantity(quantity);
    }

    public void sixteen(View view) {
        quantity = quantity + 16;
        displayQuantity(quantity);
    }

    public void thirty_two(View view) {
        quantity = quantity + 32;
        displayQuantity(quantity);
    }

    public void sixty_four(View view) {
        quantity = quantity + 64;
        displayQuantity(quantity);
    }

    //Reset Button
    public void reset(View view) {
        quantity = 0;
        displayQuantity(quantity);
        outcome = "";
//        displayOutcome(outcome);
    }


    /**
     * This method displays the given quantity value on the screen.
     */
    public void displayQuantity(int quantity) {
        TextView quantityTextView = (TextView) findViewById(
                R.id.quantity_text_view);
            quantityTextView.setText(quantity + "");
    }
}

感谢您的帮助。我过去几天试图弄清楚这一点,我不知道ServiceSuccess方法有什么问题。如果您想/需要查看更多代码,请告诉我们。

添加了异步任务YahooWeatherService

package com.oxinc.android.drate.service;

import android.net.Uri;
import android.os.AsyncTask;

import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import com.oxinc.android.drate.data.Channel;
import com.oxinc.android.drate.listener.WeatherServiceListener;

public class YahooWeatherService {
    private WeatherServiceListener listener;
    private Exception error;
    private String temperatureUnit = "C";

    public YahooWeatherService(WeatherServiceListener listener) {
        this.listener = listener;
    }

    public String getTemperatureUnit() {
        return temperatureUnit;
    }

    public void setTemperatureUnit(String temperatureUnit) {
        this.temperatureUnit = temperatureUnit;
    }

    public void refreshWeather(String location) {

        new AsyncTask<String, Void, Channel>() {
            @Override
            protected Channel doInBackground(String[] locations) {

                String location = locations[0];

                Channel channel = new Channel();

                String unit = getTemperatureUnit().equalsIgnoreCase("f") ? "f" : "c";

                String YQL = String.format("select * from weather.forecast where woeid in (select woeid from geo.places(1) where text=\"%s\") and u='" + unit + "'", location);

                String endpoint = String.format("https://query.yahooapis.com/v1/public/yql?q=%s&format=json", Uri.encode(YQL));

                try {
                    URL url = new URL(endpoint);

                    URLConnection connection = url.openConnection();
                    connection.setUseCaches(false);

                    InputStream inputStream = connection.getInputStream();

                    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                    StringBuilder result = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        result.append(line);
                    }

                    JSONObject data = new JSONObject(result.toString());

                    JSONObject queryResults = data.optJSONObject("query");

                    int count = queryResults.optInt("count");

                    if (count == 0) {
                        error = new LocationWeatherException("No weather information found for " + location);
                        return null;
                    }

                    JSONObject channelJSON = queryResults.optJSONObject("results").optJSONObject("channel");
                    channel.populate(channelJSON);

                    return channel;

                } catch (Exception e) {
                    error = e;
                }

                return null;
            }

            @Override
            protected void onPostExecute(Channel channel) {

                if (channel == null && error != null) {
                    listener.serviceFailure(error);
                } else {
                    listener.serviceSuccess(channel);
                }

            }

        }.execute(location);
    }

    public class LocationWeatherException extends Exception {
        public LocationWeatherException(String detailMessage) {
            super(detailMessage);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

根据我的理解,下面的方案中可能存在一个问题,

1)检查是否通过在输出中记录服务成功方法获得资源ID。

2)如果您没有收到问题,那么您可以检查您的服务。

3)如果你得到它然后它可能是由弃用的方法引起的,所以如果你得到资源id,请使用下面的方法。

 Drawable weatherIconDrawable =  ResourcesCompat.getDrawable(getResources(), resourceId, null);

这会对你有帮助。