Мне нужна помощь, создал приложение погода, вот код
Класс Weather
public class Weather extends AsyncTask<String, Void, String> {
private String result = "";
private HttpURLConnection urlConnection = null;
@Override
protected String doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream);
int data = reader.read();
while (data != -1) {
char current = (char) data;
result = result.concat(String.valueOf(current));
data = reader.read();
}
return result;
} catch (Exception e) {
e.printStackTrace();
} finally {
urlConnection.disconnect();
}
return null;
}
@SuppressLint("SetTextI18n")
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
JSONObject jsonObject = new JSONObject(result);
JSONObject info = new JSONObject(jsonObject.getString("main"));
JSONObject wind = new JSONObject(jsonObject.getString("wind"));
double temperature = Double.parseDouble(info.getString("temp"));
int temp_Celsius = (int) (temperature - 273.15);
String pressure = info.getString("pressure");
String humidity = info.getString("humidity");
String windSpeed = wind.getString("speed");
String place = jsonObject.getString("name");
String weather = jsonObject.getString("weather");
JSONArray array = new JSONArray(weather);
String description = "";
int id = 0;
for (int i = 0; i < array.length(); i++) {
JSONObject arrayObject = array.getJSONObject(i);
description = arrayObject.getString("description");
id = arrayObject.getInt("id");
}
setWeatherIcon(id, jsonObject.getJSONObject("sys").getLong("sunrise") * 1000,
jsonObject.getJSONObject("sys").getLong("sunset") * 1000);
MainActivity.city.setText(place.toUpperCase());
MainActivity.temperature.setText(String.valueOf(temp_Celsius + "°C"));
MainActivity.details.setText("Weather: " + description + "\n" + "Pressure: " + pressure + "hpa" + "\n" + "Humidity: " + humidity + "\n" + "Wind speed: " + windSpeed + "m/s");
} catch (Exception e) {
e.printStackTrace();
}
}
private void setWeatherIcon(int actualId, long sunrise, long sunset) {
int id = actualId / 100;
long currentTime = new Date().getTime();
if (actualId == 800) {
if (currentTime >= sunrise && currentTime < sunset) {
MainActivity.imageView.setImageResource(R.drawable.sun);
} else MainActivity.imageView.setImageResource(R.drawable.night);
} else {
if (currentTime >= sunrise && currentTime < sunset) {
switch (id) {
case 7:
MainActivity.imageView.setImageResource(R.drawable.partly_cloudy);
break;
}
} else if (currentTime <= sunrise && currentTime > sunset) {
switch (id) {
case 7:
MainActivity.imageView.setImageResource(R.drawable.night_cloudy);
break;
}
} else switch (id) {
case 2:
MainActivity.imageView.setImageResource(R.drawable.thunder);
break;
case 3:
MainActivity.imageView.setImageResource(R.drawable.storm);
break;
case 5:
MainActivity.imageView.setImageResource(R.drawable.rain);
break;
case 6:
MainActivity.imageView.setImageResource(R.drawable.snow);
break;
case 8:
MainActivity.imageView.setImageResource(R.drawable.cloud);
break;
}
}
}}
Класс Main
public class MainActivity extends AppCompatActivity {
@SuppressLint("StaticFieldLeak")
public static TextView city;
@SuppressLint("StaticFieldLeak")
public static TextView temperature;
@SuppressLint("StaticFieldLeak")
public static TextView details;
@SuppressLint("StaticFieldLeak")
public static ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
city = findViewById(R.id.city);
temperature = findViewById(R.id.temperature);
details = findViewById(R.id.details);
imageView = findViewById(R.id.weather_icon);
try {
Weather weather = new Weather();
weather.execute("http://api.openweathermap.org/data/2.5/weather?q=Yerevan&appid=53328692679f840d7be7c1d520a324d1").get();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.change_city) {
showInputDialog();
}
return false;
}
private void showInputDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Change city");
final EditText inputCity = new EditText(this);
inputCity.setInputType(InputType.TYPE_CLASS_TEXT);
builder.setView(inputCity);
builder.setPositiveButton("Change", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
try {
Weather weather = new Weather();
weather.execute("http://api.openweathermap.org/data/2.5/weather?q=" + inputCity.getText().toString() +
"&appid=53328692679f840d7be7c1d520a324d1").get();
} catch (Exception e) {
e.printStackTrace();
}
}
});
builder.show();
}
}
Есть 2 класса, вы это уже видите) но там есть несколько View элементов в MainActivity (TextView, ImageView), и их я использую в классе Weather, но их надо делать статик в MainActivity, а так код нечистый... как можно решить эту проблему??
Один из вариантов сделать класс Weather
внутренним нестатическим классом MainActivity
и тогда в нём будет неявная ссылка на класс активити MainActivity.this
, через которую вы сможете получить доступ к её полям.
Другой вариант, явно передать объект MainActivity
в класс Weather
через конструктор Weather weather = new Weather(this);
, сохранить в локальную переменную и обращаться к её полям.
public class Weather extends AsyncTask<String, Void, String> {
...
private MainActivity activity;
public Weather(MainActivity activity) {
this.activity = activity;
}
@Override
protected void onPostExecute(String result) {
...
if (activity != null) {
activity.city.setText(place.toUpperCase());
activity.temperature.setText(String.valueOf(temp_Celsius + "°C"));
activity.details.setText("Weather: " + description + "\n" + "Pressure: " + pressure + "hpa" + "\n" + "Humidity: " + humidity + "\n" + "Wind speed: " + windSpeed + "m/s");
}
...
}
public void release() {
activity = null;
}
}
В MainActivity
:
private Weather weather;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
weather = new Weather(this);
...
}
@Override
protected void onDestroy() {
super.onDestroy();
weather.release();
}
В первом варианте вы можете получить утечку активити пока не будет завершено выполнение AsyncTask
. Во втором вы можете этого избежать, вручную зануляя ссылку на активити, например, в методе onDestroy()
. Но при этом при обращении к её полям нужно будет добавить проверку на null
.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Как создать интерфейс и добавить туда весь код который находиться в методе create?
Здравствуйте, как мне организовать одновременное принятия и отправку файлов по сокетах? Подскажите алгоритм принятия и отправки файлов
Есть готовый сервер на java с использованием Datagram https://githubcom/srajat/UDP-SIP-Server но он то падает, потому что строки парсит неправильно, то запросы шлет...
Не могу отсортировать массив (скорее всего нужен по убыванию)В задании стоит задача вывести двух самых высоких людей, то есть найти два максимальных...