【问题标题】:Wrong 1st argument type. Found: 'com.example.sunshine.FetchData', required: 'android.content.Context'第一个参数类型错误。找到:'com.example.sunshine.FetchData',需要:'android.content.Context'
【发布时间】:2019-07-17 04:24:08
【问题描述】:

我想这个问题更多的是关于理解上下文以及如何正确使用它。 在谷歌搜索和“stackoverflowed”很多之后,我找不到答案。

问题:
使用 DateUtils.formatDateTime 时,我不能使用“this”作为上下文。错误信息如标题所述。

申请信息:
这是一个简单的天气应用程序,通过 JSON 检索天气信息并将其显示在屏幕上。

活动:
- MainActivity.java
- FetchData.java

MainActivity:显示信息
FetchData:从 API 获取 JSON 信息,对其进行格式化并将其发送回 MainActivity

我在 FetchData.java 活动中使用 DateUtils.formatDateTime 并且使用“this”作为上下文不起作用。 据我了解,Context 提供了调用该方法的“环境”(?)。

  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);

这使错误消失了,但我仍然不明白为什么“this”不起作用。

【问题讨论】:

    标签: java android android-context android-dateutils


    【解决方案1】:

    我在 FetchData.java 活动中使用 DateUtils.formatDateTime 并且 使用“this”作为上下文是行不通的。据我了解 上下文提供了方法所在的“环境”(?) 调用。

    你错了,Context是Android上下文,即(from documentation):

    有关应用程序环境的全局信息的接口。这 是一个抽象类,其实现由 Android 提供 系统。它允许访问特定于应用程序的资源和 类,以及对应用程序级操作的向上调用,例如 发起活动、广播和接收意图等。

    DateUtils.formatDateTime() 需要 Context 作为其参数之一。所以,你需要传递一个上下文。

    Android Activity 是 Context 的子类,因此您可以使用 this(引用自身)作为上下文,如下所示:

    public class MyActivity extends Activity {
         ...
         protected void doSomething() {
            // this refer to the MyActivity instance which is a Context.
            DateUtils.formatDateTime(this, ...);
         }
         ...
     }
    

    您需要为每个不是 Context 子类的类传递 Context。

    您不能在 AsyncTask 中使用 this,因为它不是 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.formatDateTime() 时不需要创建 DateUtils 对象,因此没有必要:

    DateUtils tempDate = new DateUtils();
    tempDate.formatDateTime(...);
    

    你可以直接调用它,因为它是一个静态方法:

    DateUtils.formatDateTime(...);
    

    【讨论】:

    • 非常感谢! :) [试图投票但由于声誉低而无法投票]
    • 太棒了,它可以帮助你!.. 不要想它,只要专注于你的旅程,别忘了在你有时间的时候为 SO 做贡献 ;)
    【解决方案2】:

    tempDate.formatDateTime(this,tempJSONWeatherData.getLong("dt"), 而不是这个,你可以传递应用程序的上下文,这指的是 FetchData 类

    【讨论】:

    • 感谢您的回答。我该怎么做呢?不幸的是,getApplicationContext() 不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-16
    • 1970-01-01
    • 1970-01-01
    • 2019-03-29
    • 1970-01-01
    • 1970-01-01
    • 2021-10-24
    相关资源
    最近更新 更多