如何修复运行时异常无法启动活动

时间:2018-06-28 11:41:10

标签: android exception

  

06-28 17:05:23.694 13262-13262 / io.hypertrack.sendeta.debug   E / AndroidRuntime:致命异常:main       进程:io.hypertrack.sendeta.debug,PID:13262       java.lang.RuntimeException:无法启动活动ComponentInfo {io.hypertrack.sendeta.debug / io.hypertrack.sendeta.activities.MainActivity}:   android.view.InflateException:二进制XML文件第4行:错误   膨胀类java.lang.reflect.Constructor
  io.hypertrack.sendeta.activities.MainActivity.onCreate(MainActivity.java:109)

    public class MainActivity extends AppCompatActivity implements LocationListener {
        protected static final int MY_PERMISSIONS_ACCESS_FINE_LOCATION = 1;

        // Time in milliseconds; only reload weather if last update is longer ago than this value
        private static final int NO_UPDATE_REQUIRED_THRESHOLD = 300000;

        private static Map<String, Integer> speedUnits = new HashMap<>(3);
        private static Map<String, Integer> pressUnits = new HashMap<>(3);
        private static boolean mappingsInitialised = false;

        Typeface weatherFont;
        Weather todayWeather = new Weather();

        TextView todayTemperature;
        TextView todayDescription;
        TextView todayWind;
        TextView todayPressure;
        TextView todayHumidity;
        TextView todaySunrise;
        TextView todaySunset;
        TextView lastUpdate;
        TextView todayIcon;
        ViewPager viewPager;
        TabLayout tabLayout;

        View appView;

        LocationManager locationManager;
        ProgressDialog progressDialog;

        int theme;
        boolean destroyed = false;

        private List<Weather> longTermWeather = new ArrayList<>();
        private List<Weather> longTermTodayWeather = new ArrayList<>();
        private List<Weather> longTermTomorrowWeather = new ArrayList<>();

        public String recentCity = "";

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            // Initialize the associated SharedPreferences file with default values
            PreferenceManager.setDefaultValues(this, R.xml.prefs, false);

            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
            setTheme(theme = getTheme(prefs.getString("theme", "fresh")));
            boolean darkTheme = theme == R.style.AppTheme_NoActionBar_Dark ||
                    theme == R.style.AppTheme_NoActionBar_Classic_Dark;
            boolean blackTheme = theme == R.style.AppTheme_NoActionBar_Black ||
                    theme == R.style.AppTheme_NoActionBar_Classic_Black;

            // Initiate activity
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_scrolling);
            appView = findViewById(R.id.viewApp);

            progressDialog = new ProgressDialog(MainActivity.this);

            // Load toolbar
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);
            if (darkTheme) {
                toolbar.setPopupTheme(R.style.AppTheme_PopupOverlay_Dark);
            } else if (blackTheme) {
                toolbar.setPopupTheme(R.style.AppTheme_PopupOverlay_Black);
            }

            // Initialize textboxes
            todayTemperature = (TextView) findViewById(R.id.todayTemperature);
            todayDescription = (TextView) findViewById(R.id.todayDescription);
            todayWind = (TextView) findViewById(R.id.todayWind);
            todayPressure = (TextView) findViewById(R.id.todayPressure);
            todayHumidity = (TextView) findViewById(R.id.todayHumidity);
            todaySunrise = (TextView) findViewById(R.id.todaySunrise);
            todaySunset = (TextView) findViewById(R.id.todaySunset);
            lastUpdate = (TextView) findViewById(R.id.lastUpdate);
            todayIcon = (TextView) findViewById(R.id.todayIcon);
            weatherFont = Typeface.createFromAsset(this.getAssets(), "fonts/weather.ttf");
            todayIcon.setTypeface(weatherFont);

            // Initialize viewPager
            viewPager = (ViewPager) findViewById(R.id.viewPager);
            tabLayout = (TabLayout) findViewById(R.id.tabs);

            destroyed = false;

            initMappings();

            // Preload data from cache
            preloadWeather();
            updateLastUpdateTime();

            // Set autoupdater
            AlarmReceiver.setRecurringAlarm(this);
        }

        public WeatherRecyclerAdapter getAdapter(int id) {
            WeatherRecyclerAdapter weatherRecyclerAdapter;
            if (id == 0) {
                weatherRecyclerAdapter = new WeatherRecyclerAdapter(this, longTermTodayWeather);
            } else if (id == 1) {
                weatherRecyclerAdapter = new WeatherRecyclerAdapter(this, longTermTomorrowWeather);
            } else {
                weatherRecyclerAdapter = new WeatherRecyclerAdapter(this, longTermWeather);
            }
            return weatherRecyclerAdapter;
        }

        @Override
        public void onStart() {
            super.onStart();
            updateTodayWeatherUI();
            updateLongTermWeatherUI();
        }

        @Override
        public void onResume() {
            super.onResume();
            if (getTheme(PreferenceManager.getDefaultSharedPreferences(this).getString("theme", "fresh")) != theme) {
                // Restart activity to apply theme
                overridePendingTransition(0, 0);
                finish();
                overridePendingTransition(0, 0);
                startActivity(getIntent());
            } else if (shouldUpdate() && isNetworkAvailable()) {
                getTodayWeather();
                getLongTermWeather();
            }
        }

        @Override
        protected void onDestroy() {
            super.onDestroy();
            destroyed = true;

            if (locationManager != null) {
                try {
                    locationManager.removeUpdates(MainActivity.this);
                } catch (SecurityException e) {
                    e.printStackTrace();
                }
            }
        }

        private void preloadWeather() {
            SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);

            String lastToday = sp.getString("lastToday", "");
            if (!lastToday.isEmpty()) {
                new TodayWeatherTask(this, this, progressDialog).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "cachedResponse", lastToday);
            }
            String lastLongterm = sp.getString("lastLongterm", "");
            if (!lastLongterm.isEmpty()) {
                new LongTermWeatherTask(this, this, progressDialog).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "cachedResponse", lastLongterm);
            }
        }

        private void getTodayWeather() {
            new TodayWeatherTask(this, this, progressDialog).execute();
        }

        private void getLongTermWeather() {
            new LongTermWeatherTask(this, this, progressDialog).execute();
        }

        private void searchCities() {
            AlertDialog.Builder alert = new AlertDialog.Builder(this);
            alert.setTitle(this.getString(R.string.search_title));
            final EditText input = new EditText(this);
            input.setInputType(InputType.TYPE_CLASS_TEXT);
            input.setMaxLines(1);
            input.setSingleLine(true);
            alert.setView(input, 32, 0, 32, 0);
            alert.setPositiveButton(R.string.dialog_ok, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    String result = input.getText().toString();
                    if (!result.isEmpty()) {
                        saveLocation(result);
                    }
                }
            });
            alert.setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    // Cancelled
                }
            });
            alert.show();
        }

        private void saveLocation(String result) {
            SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
            recentCity = preferences.getString("city", Constants.DEFAULT_CITY);

            SharedPreferences.Editor editor = preferences.edit();
            editor.putString("city", result);
            editor.commit();

            if (!recentCity.equals(result)) {
                // New location, update weather
                getTodayWeather();
                getLongTermWeather();
            }
        }

        private void aboutDialog() {
            AlertDialog.Builder alert = new AlertDialog.Builder(this);
            alert.setTitle("Forecastie");
            final WebView webView = new WebView(this);
            String about = "<p>1.6.1</p>" +
                    "<p>A lightweight, opensource weather app.</p>" +
                    "<p>Developed by <a href='mailto:t.martykan@gmail.com'>Tomas Martykan</a></p>" +
                    "<p>Data provided by <a href='https://openweathermap.org/'>OpenWeatherMap</a>, under the <a href='http://creativecommons.org/licenses/by-sa/2.0/'>Creative Commons license</a>" +
                    "<p>Icons are <a href='https://erikflowers.github.io/weather-icons/'>Weather Icons</a>, by <a href='http://www.twitter.com/artill'>Lukas Bischoff</a> and <a href='http://www.twitter.com/Erik_UX'>Erik Flowers</a>, under the <a href='http://scripts.sil.org/OFL'>SIL OFL 1.1</a> licence.";
            TypedArray ta = obtainStyledAttributes(new int[]{android.R.attr.textColorPrimary, R.attr.colorAccent});
            String textColor = String.format("#%06X", (0xFFFFFF & ta.getColor(0, Color.BLACK)));
            String accentColor = String.format("#%06X", (0xFFFFFF & ta.getColor(1, Color.BLUE)));
            ta.recycle();
            about = "<style media=\"screen\" type=\"text/css\">" +
                    "body {\n" +
                    "    color:" + textColor + ";\n" +
                    "}\n" +
                    "a:link {color:" + accentColor + "}\n" +
                    "</style>" +
                    about;
            webView.setBackgroundColor(Color.TRANSPARENT);
            webView.loadData(about, "text/html", "UTF-8");
            alert.setView(webView, 32, 0, 32, 0);
            alert.setPositiveButton(R.string.dialog_ok, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {

                }
            });
            alert.show();
        }

        private String setWeatherIcon(int actualId, int hourOfDay) {
            int id = actualId / 100;
            String icon = "";
            if (actualId == 800) {
                if (hourOfDay >= 7 && hourOfDay < 20) {
                    icon = this.getString(R.string.weather_sunny);
                } else {
                    icon = this.getString(R.string.weather_clear_night);
                }
            } else {
                switch (id) {
                    case 2:
                        icon = this.getString(R.string.weather_thunder);
                        break;
                    case 3:
                        icon = this.getString(R.string.weather_drizzle);
                        break;
                    case 7:
                        icon = this.getString(R.string.weather_foggy);
                        break;
                    case 8:
                        icon = this.getString(R.string.weather_cloudy);
                        break;
                    case 6:
                        icon = this.getString(R.string.weather_snowy);
                        break;
                    case 5:
                        icon = this.getString(R.string.weather_rainy);
                        break;
                }
            }
            return icon;
        }

        public static String getRainString(JSONObject rainObj) {
            String rain = "0";
            if (rainObj != null) {
                rain = rainObj.optString("3h", "fail");
                if ("fail".equals(rain)) {
                    rain = rainObj.optString("1h", "0");
                }
            }
            return rain;
        }

        private ParseResult parseTodayJson(String result) {
            try {
                JSONObject reader = new JSONObject(result);

                final String code = reader.optString("cod");
                if ("404".equals(code)) {
                    return ParseResult.CITY_NOT_FOUND;
                }

                String city = reader.getString("name");
                String country = "";
                JSONObject countryObj = reader.optJSONObject("sys");
                if (countryObj != null) {
                    country = countryObj.getString("country");
                    todayWeather.setSunrise(countryObj.getString("sunrise"));
                    todayWeather.setSunset(countryObj.getString("sunset"));
                }
                todayWeather.setCity(city);
                todayWeather.setCountry(country);

                JSONObject coordinates = reader.getJSONObject("coord");
                if (coordinates != null) {
                    SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
                    sp.edit().putFloat("latitude", (float) coordinates.getDouble("lon")).putFloat("longitude", (float) coordinates.getDouble("lat")).commit();
                }

                JSONObject main = reader.getJSONObject("main");

                todayWeather.setTemperature(main.getString("temp"));
                todayWeather.setDescription(reader.getJSONArray("weather").getJSONObject(0).getString("description"));
                JSONObject windObj = reader.getJSONObject("wind");
                todayWeather.setWind(windObj.getString("speed"));
                if (windObj.has("deg")) {
                    todayWeather.setWindDirectionDegree(windObj.getDouble("deg"));
                } else {
                    Log.e("parseTodayJson", "No wind direction available");
                    todayWeather.setWindDirectionDegree(null);
                }
                todayWeather.setPressure(main.getString("pressure"));
                todayWeather.setHumidity(main.getString("humidity"));

                JSONObject rainObj = reader.optJSONObject("rain");
                String rain;
                if (rainObj != null) {
                    rain = getRainString(rainObj);
                } else {
                    JSONObject snowObj = reader.optJSONObject("snow");
                    if (snowObj != null) {
                        rain = getRainString(snowObj);
                    } else {
                        rain = "0";
                    }
                }
                todayWeather.setRain(rain);

                final String idString = reader.getJSONArray("weather").getJSONObject(0).getString("id");
                todayWeather.setId(idString);
                todayWeather.setIcon(setWeatherIcon(Integer.parseInt(idString), Calendar.getInstance().get(Calendar.HOUR_OF_DAY)));

                SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(MainActivity.this).edit();
                editor.putString("lastToday", result);
                editor.commit();

            } catch (JSONException e) {
                Log.e("JSONException Data", result);
                e.printStackTrace();
                return ParseResult.JSON_EXCEPTION;
            }

            return ParseResult.OK;
        }

        private void updateTodayWeatherUI() {
            try {
                if (todayWeather.getCountry().isEmpty()) {
                    preloadWeather();
                    return;
                }
            } catch (Exception e) {
                preloadWeather();
                return;
            }
            String city = todayWeather.getCity();
            String country = todayWeather.getCountry();
            DateFormat timeFormat = android.text.format.DateFormat.getTimeFormat(getApplicationContext());
            getSupportActionBar().setTitle(city + (country.isEmpty() ? "" : ", " + country));

            SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);

            // Temperature
            float temperature = UnitConvertor.convertTemperature(Float.parseFloat(todayWeather.getTemperature()), sp);
            if (sp.getBoolean("temperatureInteger", false)) {
                temperature = Math.round(temperature);
            }

            // Rain
            double rain = Double.parseDouble(todayWeather.getRain());
            String rainString = UnitConvertor.getRainString(rain, sp);

            // Wind
            double wind;
            try {
                wind = Double.parseDouble(todayWeather.getWind());
            } catch (Exception e) {
                e.printStackTrace();
                wind = 0;
            }
            wind = UnitConvertor.convertWind(wind, sp);

            // Pressure
            double pressure = UnitConvertor.convertPressure((float) Double.parseDouble(todayWeather.getPressure()), sp);

            todayTemperature.setText(new DecimalFormat("0.#").format(temperature) + " " + sp.getString("unit", "°C"));
            todayDescription.setText(todayWeather.getDescription().substring(0, 1).toUpperCase() +
                    todayWeather.getDescription().substring(1) + rainString);
            if (sp.getString("speedUnit", "m/s").equals("bft")) {
                todayWind.setText(getString(R.string.wind) + ": " +
                        UnitConvertor.getBeaufortName((int) wind) +
                        (todayWeather.isWindDirectionAvailable() ? " " + getWindDirectionString(sp, this, todayWeather) : ""));
            } else {
                todayWind.setText(getString(R.string.wind) + ": " + new DecimalFormat("0.0").format(wind) + " " +
                        localize(sp, "speedUnit", "m/s") +
                        (todayWeather.isWindDirectionAvailable() ? " " + getWindDirectionString(sp, this, todayWeather) : ""));
            }
            todayPressure.setText(getString(R.string.pressure) + ": " + new DecimalFormat("0.0").format(pressure) + " " +
                    localize(sp, "pressureUnit", "hPa"));
            todayHumidity.setText(getString(R.string.humidity) + ": " + todayWeather.getHumidity() + " %");
            todaySunrise.setText(getString(R.string.sunrise) + ": " + timeFormat.format(todayWeather.getSunrise()));
            todaySunset.setText(getString(R.string.sunset) + ": " + timeFormat.format(todayWeather.getSunset()));
            todayIcon.setText(todayWeather.getIcon());
        }

        public ParseResult parseLongTermJson(String result) {
            int i;
            try {
                JSONObject reader = new JSONObject(result);

                final String code = reader.optString("cod");
                if ("404".equals(code)) {
                    if (longTermWeather == null) {
                        longTermWeather = new ArrayList<>();
                        longTermTodayWeather = new ArrayList<>();
                        longTermTomorrowWeather = new ArrayList<>();
                    }
                    return ParseResult.CITY_NOT_FOUND;
                }

                longTermWeather = new ArrayList<>();
                longTermTodayWeather = new ArrayList<>();
                longTermTomorrowWeather = new ArrayList<>();

                JSONArray list = reader.getJSONArray("list");
                for (i = 0; i < list.length(); i++) {
                    Weather weather = new Weather();

                    JSONObject listItem = list.getJSONObject(i);
                    JSONObject main = listItem.getJSONObject("main");

                    weather.setDate(listItem.getString("dt"));
                    weather.setTemperature(main.getString("temp"));
                    weather.setDescription(listItem.optJSONArray("weather").getJSONObject(0).getString("description"));
                    JSONObject windObj = listItem.optJSONObject("wind");
                    if (windObj != null) {
                        weather.setWind(windObj.getString("speed"));
                        weather.setWindDirectionDegree(windObj.getDouble("deg"));
                    }
                    weather.setPressure(main.getString("pressure"));
                    weather.setHumidity(main.getString("humidity"));

                    JSONObject rainObj = listItem.optJSONObject("rain");
                    String rain = "";
                    if (rainObj != null) {
                        rain = getRainString(rainObj);
                    } else {
                        JSONObject snowObj = listItem.optJSONObject("snow");
                        if (snowObj != null) {
                            rain = getRainString(snowObj);
                        } else {
                            rain = "0";
                        }
                    }
                    weather.setRain(rain);

                    final String idString = listItem.optJSONArray("weather").getJSONObject(0).getString("id");
                    weather.setId(idString);

                    final String dateMsString = listItem.getString("dt") + "000";
                    Calendar cal = Calendar.getInstance();
                    cal.setTimeInMillis(Long.parseLong(dateMsString));
                    weather.setIcon(setWeatherIcon(Integer.parseInt(idString), cal.get(Calendar.HOUR_OF_DAY)));

                    Calendar today = Calendar.getInstance();
                    if (cal.get(Calendar.DAY_OF_YEAR) == today.get(Calendar.DAY_OF_YEAR)) {
                        longTermTodayWeather.add(weather);
                    } else if (cal.get(Calendar.DAY_OF_YEAR) == today.get(Calendar.DAY_OF_YEAR) + 1) {
                        longTermTomorrowWeather.add(weather);
                    } else {
                        longTermWeather.add(weather);
                    }
                }
                SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(MainActivity.this).edit();
                editor.putString("lastLongterm", result);
                editor.commit();
            } catch (JSONException e) {
                Log.e("JSONException Data", result);
                e.printStackTrace();
                return ParseResult.JSON_EXCEPTION;
            }

            return ParseResult.OK;
        }

        private void updateLongTermWeatherUI() {
            if (destroyed) {
                return;
            }

            ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());

            Bundle bundleToday = new Bundle();
            bundleToday.putInt("day", 0);
            RecyclerViewFragment recyclerViewFragmentToday = new RecyclerViewFragment();
            recyclerViewFragmentToday.setArguments(bundleToday);
            viewPagerAdapter.addFragment(recyclerViewFragmentToday, getString(R.string.today));

            Bundle bundleTomorrow = new Bundle();
            bundleTomorrow.putInt("day", 1);
            RecyclerViewFragment recyclerViewFragmentTomorrow = new RecyclerViewFragment();
            recyclerViewFragmentTomorrow.setArguments(bundleTomorrow);
            viewPagerAdapter.addFragment(recyclerViewFragmentTomorrow, getString(R.string.tomorrow));

            Bundle bundle = new Bundle();
            bundle.putInt("day", 2);
            RecyclerViewFragment recyclerViewFragment = new RecyclerViewFragment();
            recyclerViewFragment.setArguments(bundle);
            viewPagerAdapter.addFragment(recyclerViewFragment, getString(R.string.later));

            int currentPage = viewPager.getCurrentItem();

            viewPagerAdapter.notifyDataSetChanged();
            viewPager.setAdapter(viewPagerAdapter);
            tabLayout.setupWithViewPager(viewPager);

            if (currentPage == 0 && longTermTodayWeather.isEmpty()) {
                currentPage = 1;
            }
            viewPager.setCurrentItem(currentPage, false);
        }

        private boolean isNetworkAvailable() {
            ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
            return activeNetworkInfo != null && activeNetworkInfo.isConnected();
        }

        private boolean shouldUpdate() {
            long lastUpdate = PreferenceManager.getDefaultSharedPreferences(this).getLong("lastUpdate", -1);
            boolean cityChanged = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("cityChanged", false);
            // Update if never checked or last update is longer ago than specified threshold
            return cityChanged || lastUpdate < 0 || (Calendar.getInstance().getTimeInMillis() - lastUpdate) > NO_UPDATE_REQUIRED_THRESHOLD;
        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.menu_main, menu);
            return true;
        }
    }

0 个答案:

没有答案