简体   繁体   中英

Wrong 1st argument type. Found: 'com.example.sunshine.FetchData', required: 'android.content.Context'

I guess this question is more about understanding context and how to use it properly. After having googled and "stackoverflowed" a lot I could not find the answer.

Problem:
when using DateUtils.formatDateTime I cannot use "this" as a context. The error message is as described in the title.

Application Info:
This is a simple weather app retrieving weather information via JSON and displaying it on the screen.

Activities:
- MainActivity.java
- FetchData.java

MainActivity: displaying the info
FetchData: getting JSON info from the API, formatting it and sending it back to MainActivity

I am using DateUtils.formatDateTime in the FetchData.java activity and using "this" as a context does not work. As from my understanding Context provided the "environment" (?) of where the method is being called.

  1. Why is the "environment" of FetchData not valid?
  2. What content should be provided instead?

Help is much appreciated. Thank you :)

Code:

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

Edit : I just realized I left out an important detail, namely this activity extends AsyncTask . After some further research apparently you provide the context bei adding WeakReference and then adding context in the constructor.

I added the following code:

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 made the error disappear but I still don't understand why "this" doesn't work.

I am using DateUtils.formatDateTime in the FetchData.java activity and using "this" as a context does not work. As from my understanding Context provided the "environment" (?) of where the method is being called.

You're incorrect, Context is Android context which is (from documentation ):

Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc.

DateUtils.formatDateTime() needs Context as one of its parameter. So, you need to pass a context.

Android Activity is sub class of Context, so you can use this (which refer to itself) as the context like the following:

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

You need to pass the Context for every class that is not a Context subclass.

You can't use this in AsyncTask because it's not a Context subclass. So, you need to pass the Context using WeakReference to avoid Context leaking , like the following:

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, ...);
     }
}

Last, you don't need to create a DateUtils object when calling DateUtils.formatDateTime() , so this isn't necessary:

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

You can directly call it because it's a static method:

DateUtils.formatDateTime(...);

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM