Неверный 1-й тип аргумента. Найдено: 'com.example.sunshine.FetchData', обязательно: 'android.content.Context'
Я думаю, что этот вопрос больше о понимании контекста и о том, как правильно его использовать. После того, как я много гуглил и "переполнялся стеком", я не мог найти ответ.
Проблема:
при использовании DateUtils.formatDateTime я не могу использовать "это" в качестве контекста. Сообщение об ошибке, как описано в заголовке.
Информация о приложении:
Это простое приложение погоды, которое получает информацию о погоде через JSON и отображает ее на экране.
Мероприятия:
- MainActivity.java
- FetchData.java
MainActivity: отображение информации
FetchData: получение информации JSON из API, ее форматирование и отправка обратно в MainActivity
Я использую DateUtils.formatDateTime в действии FetchData.java, и использование этого в качестве контекста не работает. Насколько я понимаю, Контекст предоставил "среду" (?) Того, где вызывается метод.
- Почему "среда" FetchData недействительна?
- Какой контент должен быть предоставлен вместо?
Помощь очень ценится. Спасибо:)
Код:
private ArrayList<String> getWeatherDataFromJson(String forecastJsontStr) throws JSONException {
ArrayList<String> dailyWeatherInfo = new ArrayList<>();
int dataCount;
DateUtils tempDate = new DateUtils();
JSONObject weatherData = new JSONObject(forecastJsontStr);
JSONArray threeHourWeatherData = weatherData.getJSONArray(JSON_LIST);
dataCount = weatherData.getInt("cnt");
JSONObject tempJSONWeatherData;
for (int i = 0; i < dataCount; i++) {
tempJSONWeatherData = threeHourWeatherData.getJSONObject(i);
tempDate.formatDateTime(this,tempJSONWeatherData.getLong("dt"),
DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY |
DateUtils.FORMAT_ABBREV_ALL);
[more code here]
return dailyWeatherInfo;
}
Изменить: я только что понял, что я пропустил важную деталь, а именно это действие расширяется AsyncTask
, После некоторых дальнейших исследований, по-видимому, вы предоставляете контекст для добавления WeakReference
а затем добавить контекст в конструкторе.
Я добавил следующий код:
private WeakReference<Context> contextWeakReference;
public FetchData (Content context) {
contextWeakReference = new WeakReference<>();
}
tempDate.formatDateTime(contextWeakReference.get(),tempJSONWeatherData.getLong("dt"),
DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY |
DateUtils.FORMAT_ABBREV_ALL);
Это заставило ошибку исчезнуть, но я все еще не понимаю, почему "это" не работает.
2 ответа
Я использую DateUtils.formatDateTime в действии FetchData.java, и использование этого в качестве контекста не работает. Насколько я понимаю, Контекст предоставил "среду" (?) Того, где вызывается метод.
Вы не правы, Context - это контекст Android, который ( из документации):
Интерфейс для глобальной информации о среде приложения. Это абстрактный класс, реализация которого обеспечивается системой Android. Он позволяет получить доступ к ресурсам и классам, относящимся к конкретному приложению, а также к дополнительным вызовам для операций на уровне приложения, таких как запуск, широковещание и получение, и т. Д.
DateUtils.formatDateTime()
Контекст нужен как один из его параметров. Итак, вам нужно передать контекст.
Android Activity
является подклассом контекста, так что вы можете использовать this
(которые ссылаются на себя) в качестве контекста, подобного следующему:
public class MyActivity extends Activity {
...
protected void doSomething() {
// this refer to the MyActivity instance which is a Context.
DateUtils.formatDateTime(this, ...);
}
...
}
Вам необходимо передать контекст для каждого класса, который не является подклассом контекста.
Вы не можете использовать this
в AsyncTask, потому что это не подкласс Context. Итак, вам нужно передать контекст с помощью WeakReference
избежать Context leaking
, вроде следующего:
private class AsyncTaskRunner extends AsyncTask<String, String, String> {
private WeakReference<Context> contextWeakReference;
public FetchData (Content context) {
contextWeakReference = new WeakReference<>();
}
private void doSomething() {
// We have the context from the WeakReference
Context context = contextWeakReference.get();
DateUtils.formatDateTime(context, ...);
}
}
Наконец, вам не нужно создавать объект DateUtils при вызове DateUtils.formatDateTime()
так что в этом нет необходимости:
DateUtils tempDate = new DateUtils();
tempDate.formatDateTime(...);
Вы можете напрямую вызвать его, потому что это статический метод:
DateUtils.formatDateTime(...);
tempDate.formatDateTime(this,tempJSONWeatherData.getLong("dt"), вместо этого вы можете передать контекст приложения, это относится к классу FetchData