Неверный 1-й тип аргумента. Найдено: 'com.example.sunshine.FetchData', обязательно: 'android.content.Context'

Я думаю, что этот вопрос больше о понимании контекста и о том, как правильно его использовать. После того, как я много гуглил и "переполнялся стеком", я не мог найти ответ.

Проблема:
при использовании DateUtils.formatDateTime я не могу использовать "это" в качестве контекста. Сообщение об ошибке, как описано в заголовке.

Информация о приложении:
Это простое приложение погоды, которое получает информацию о погоде через JSON и отображает ее на экране.

Мероприятия:
- MainActivity.java
- FetchData.java

MainActivity: отображение информации
FetchData: получение информации JSON из API, ее форматирование и отправка обратно в MainActivity

Я использую DateUtils.formatDateTime в действии FetchData.java, и использование этого в качестве контекста не работает. Насколько я понимаю, Контекст предоставил "среду" (?) Того, где вызывается метод.

  1. Почему "среда" FetchData недействительна?
  2. Какой контент должен быть предоставлен вместо?

Помощь очень ценится. Спасибо:)

Код:

    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

Другие вопросы по тегам