Java 对非静态字段和JSON对象感到困惑

Java 对非静态字段和JSON对象感到困惑,java,android,android-studio,Java,Android,Android Studio,我正在学习使用RESTAPI,制作一个应用程序,使用yahoo weather来显示今天的天气。我制作了一个AsyncTask、一个自定义适配器和一个WeatherData类,我在MainActivity中调用它。不过,我在使用这个WeatherData类和自定义适配器时遇到了一些问题 在适配器中,我尝试从天气数据类调用JSON对象时出错。它表示非静态字段“weather”和“date”不能从静态上下文中引用。我试着阅读静态上下文,但它确实让我搞不清楚它是什么,它做什么 第二个问题是,我的Asy

我正在学习使用RESTAPI,制作一个应用程序,使用yahoo weather来显示今天的天气。我制作了一个AsyncTask、一个自定义适配器和一个WeatherData类,我在MainActivity中调用它。不过,我在使用这个WeatherData类和自定义适配器时遇到了一些问题

在适配器中,我尝试从天气数据类调用JSON对象时出错。它表示非静态字段“weather”和“date”不能从静态上下文中引用。我试着阅读静态上下文,但它确实让我搞不清楚它是什么,它做什么

第二个问题是,我的AsyncTask现在在尝试将日期和天气添加到weatherdata ArrayList时也会出现错误。它说WeatherData中的WeatherData(JSONobject)不能应用于JSONobject java.lang.String。我认为这与我在WeatherData类中使用weather和date作为对象,然后尝试在arraylist中将它们作为字符串使用有关。我试图通过简单地在WeatherData类中将它们更改为字符串来修复它,但随后我得到了各种各样的新错误。有人能帮我解决哪里出了问题吗

这是我主要活动的一部分,我称之为数据:

public void getData(View view) {
    ClassAsyncTask task = new ClassAsyncTask(this);
    task.execute(chosenloc);
}

public void setData(ArrayList<WeatherData> weatherdata) {
    // Construct the data source
    ArrayList<WeatherData> arrayOfWeather = new ArrayList<WeatherData>();
    // Create the adapter to convert the array to views
    CustomArrayAdapter adapter = new CustomArrayAdapter(this, arrayOfWeather);
    // Attach the adapter to a Listview
    ListView listView = (ListView) findViewById(R.id.weatherListView);
    listView.setAdapter(adapter);
}
public void getData(视图){
ClassAsyncTask任务=新建ClassAsyncTask(此任务);
任务执行(chosenloc);
}
公共无效设置数据(ArrayList weatherdata){
//构建数据源
ArrayList arrayOfWeather=新的ArrayList();
//创建适配器以将阵列转换为视图
CustomArrayAdapter=新的CustomArrayAdapter(此,arrayOfWeather);
//将适配器连接到Listview
ListView ListView=(ListView)findViewById(R.id.weatherListView);
setAdapter(适配器);
}
这是我的自定义适配器:

public class CustomArrayAdapter extends ArrayAdapter<WeatherData> {
public CustomArrayAdapter(Context context, ArrayList<WeatherData> weatherdata){
    super(context, 0, weatherdata);
}

@Override
public View getView(int position, View convertView, ViewGroup parent){
    // Get the data item for this position
    WeatherData weather = getItem(position);
    // Check if an exising view is being reused, otherwise inflate the view
    if (convertView == null){
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.custom_array_layout, parent, false);
    }
    // Lookup view for data population
    TextView date = (TextView) convertView.findViewById(R.id.date);
    TextView weather = (TextView) convertView.findViewById(R.id.weather);

    // Populate the data into the template view using the data object
    date.setText(WeatherData.date);
    weather.setText(WeatherData.weather);

    // Return the completed view to render on screen
    return convertView;
}
}
公共类CustomArrayAdapter扩展了ArrayAdapter{
公共CustomArrayAdapter(上下文,ArrayList weatherdata){
超级(上下文,0,天气数据);
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
//获取此职位的数据项
WeatherData weather=getItem(位置);
//检查是否重复使用现有视图,否则将视图充气
if(convertView==null){
convertView=LayoutInflater.from(getContext()).flate(R.layout.custom\u array\u layout,parent,false);
}
//数据填充的查找视图
TextView日期=(TextView)convertView.findViewById(R.id.date);
TextView天气=(TextView)convertView.findViewById(R.id.weather);
//使用数据对象将数据填充到模板视图中
date.setText(WeatherData.date);
weather.setText(WeatherData.weather);
//返回要在屏幕上渲染的已完成视图
返回视图;
}
}
我的WeatherData类:

public class WeatherData {
// Fields
public JSONObject date;
public String weather;

// Constructor
public WeatherData(JSONObject object) {
    try {
        JSONArray dates = object.getJSONArray("date");
        JSONArray weather = object.getJSONArray("text");
    } catch (JSONException e) {
        e.printStackTrace();
    }
}
    // Method to convert an array of JSON objects into a list of objects
    public static ArrayList<WeatherData> fromJson(JSONArray jsonObjects){
        ArrayList<WeatherData> weather = new ArrayList<WeatherData>();
        for (int i = 0; i < jsonObjects.length(); i++) {
            try {
                weather.add(new WeatherData(jsonObjects.getJSONObject(i)));
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return weather;
    }
}
公共类天气数据{
//田地
公共JSONObject日期;
公众天气;
//建造师
公共天气数据(JSONObject对象){
试一试{
JSONArray dates=object.getJSONArray(“日期”);
JSONArray weather=object.getJSONArray(“文本”);
}捕获(JSONException e){
e、 printStackTrace();
}
}
//方法将JSON对象数组转换为对象列表
来自JSON的公共静态ArrayList(JSONArray JSONObject){
ArrayList weather=新建ArrayList();
for(int i=0;i
最后是AsyncTask中解析JSON的部分:

protected void onPostExecute(String result){
    super.onPostExecute(result);

    // Alert user if nothing was found
    if(result.length() == 0){
        Toast.makeText(context, "Nothing was found", Toast.LENGTH_SHORT).show();
    }
    else {
        // Parse JSON
        ArrayList<WeatherData> weatherdata = new ArrayList<>();
        try {
            JSONObject respObj = new JSONObject(result);
            JSONObject forecastObj = respObj.getJSONObject("forecast");
            JSONArray dates = forecastObj.getJSONArray("date");
            JSONArray weatherArray = forecastObj.getJSONArray("text");

            for (int i = 0; i<dates.length(); i++){
                JSONObject date = dates.getJSONObject(i);
                String weather = date.getString("text");
                weatherdata.add(new WeatherData(date, weather));
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        // Update MainActivity
        this.activity.setData(weatherdata);
    }
}
受保护的void onPostExecute(字符串结果){
super.onPostExecute(结果);
//如果未找到任何内容,请通知用户
if(result.length()==0){
Toast.makeText(上下文,“未找到任何内容”,Toast.LENGTH_SHORT.show();
}
否则{
//解析JSON
ArrayList weatherdata=新的ArrayList();
试一试{
JSONObject respObj=新JSONObject(结果);
JSONObject ForecastObject=respObj.getJSONObject(“预测”);
JSONArray dates=forecastObj.getJSONArray(“日期”);
JSONArray weatherArray=forecastObj.getJSONArray(“文本”);

对于(int i=0;i您有很多语义错误,理解静态和非静态的差异和细微差别非常重要,但要修复代码,只需注意您在何处使用的变量。我不会为您通读Yahoo weather API,所以我在这里以一般方式展示一些内容

固定代码如下:

这应该是您的
getView

// Get the data item for this position
WeatherData weather = getItem(position);
// Check if an exising view is being reused, otherwise inflate the view
if (convertView == null){
    convertView = LayoutInflater.from(getContext()).inflate(R.layout.custom_array_layout, parent, false);
}
// CHANGED HERE the textView "weather` had the same name of the "WeatherData" defined a few lines above
// Lookup view for data population
TextView textDate = (TextView) convertView.findViewById(R.id.date);
TextView textWeather = (TextView) convertView.findViewById(R.id.weather);

// CHANGED HERE to properly call the textView methods and to read the fields from the instance of "WeatherData"
// Populate the data into the template view using the data object
textDate.setText(weather.date);
textWeather.setText(weather.weather);

// Return the completed view to render on screen
return convertView;
也是“WeatherData”的构造器是不合逻辑的,会导致NPE。我不知道你想在那里实现什么,但是当你写
JSONArray dates=object…
时,你提取的信息会被添加到这个
JSONArray
中,然后被扔掉。字段
public JSONObject date
public String weather
永远不会出现已初始化,不包含任何有用的信息。您可能希望执行以下操作:

// Fields
public String val1;
public String val2;
public String val3;
  ... any value necessary

// Constructor
public WeatherData(JSONObject object) {
    try {
         val1 = object.optString("val1");
         val2 = object.optString("val2");
         val3 = object.optString("val3");
        ... parse here EVERYTHING from the object
    } catch (JSONException e) {
        e.printStackTrace();
    }
}
另外,在
postExecute
上,您试图创建新的
WeatherData
并将两个值传递给它,就像这样
new WeatherData(date,weather)
。再次阅读
WeatherData
构造函数,它只使用一个值,即
JsonObject

最后一个是性能任务,您不应该将
字符串
返回到onPostExecute。您应该执行一个返回
ArrayList结果
的异步任务。然后所有解析代码都应该在
后台执行

编辑:异步任务示例

   public class MyAsyncTask extends AsyncTask<String, Integer, List<WeatherObject>>{

      @Override protected List<WeatherObject> doInBackground(String... params) {
         // here you call the API and parse the results
         // return ArrayList<WeatherObject> if successful, or `null` if failed
         return null;
      }

      @Override protected void onPostExecute(List<WeatherObject> weatherObjectList) {
           // here you simply check for null and use the List
           if(weatherObjectList == null){
               // fail to load data
           } else {
               // set data to adapter
           }
      }
   }
公共类MyAsyncTask扩展了AsyncTask{
@覆盖受保护列表doInBackground(字符串…参数){