2017-01-23 9 views
0

У меня возникла странная проблема в моем приложении. Я пытаюсь обновить TextViews из другого класса (а не Activity). Я могу сделать это двумя способами, позвонив перегруженным getUpdate() методам:findViewById, вызванный из другого класса, возвращает null иногда

Вот как я их называю от моего MainActivity: Эти способы работают нормально.

public boolean onOptionsItemSelected(MenuItem item) { 
    int id = item.getItemId(); 
    switch (id) { 
     case R.id.menu_location_button: 
      if (this.cwu == null) 
       this.cwu = new CurrentWeatherUpdater(this); 
      this.cwu.getUpdate(lf.getLongitude(), lf.getLatitude()); 
      break; 
      . 
      . 
      . 
    } 
    return super.onOptionsItemSelected(item); 
} 

Это один не делает:

private void handleIntent(Intent intent) { 
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) { 
     String query = intent.getStringExtra(SearchManager.QUERY); 
     if (this.cwu == null) 
      this.cwu = new CurrentWeatherUpdater(this); 
     this.cwu.getUpdate(query); 
    } 
} 

query получен от SearchView

CurrentWeatherUpdater cwu; объявлен в MainActivity.java

Это мой CurrentWeatherUpdater класс:

public class CurrentWeatherUpdater extends Updater{ 
private TextView city; 
private TextView temp; 
private TextView desc; 
private TextView humidity; 
private TextView pressure; 
private TextView wind; 

public CurrentWeatherUpdater(Context context) { 
    super(context); 
    this.city = (TextView) ((Activity)context).findViewById(R.id.city_name); 
    this.temp = (TextView) ((Activity)context).findViewById(R.id.current_temperature); 
    this.desc = (TextView) ((Activity)context).findViewById(R.id.current_weather_desc); 
    this.humidity = (TextView) ((Activity)context).findViewById(R.id.humidity); 
    this.pressure = (TextView) ((Activity)context).findViewById(R.id.pressure); 
    this.wind = (TextView) ((Activity)context).findViewById(R.id.wind); 
} 

public void getUpdate(String cityName) { 
    updateView(super.getUpdate(Updater.REQUEST_WEATHER, cityName)); 
} 

public void getUpdate(double longitude, double latitude) { 
    updateView(super.getUpdate(Updater.REQUEST_WEATHER, longitude, latitude)); 
} 

private void updateView(JSONObject result) { 
    try { 
     if (result.getInt("cod") == 200) { 
      this.city.setText(result.getString("name")); 
      JSONObject main = result.getJSONObject("main"); 
      temp.setText(Integer.toString((int) Math.round(Double.parseDouble(main.getString("temp")))) + "\u00b0"); 
      pressure.setText(main.getString("pressure") + "hPa"); 
      humidity.setText(main.getString("humidity") + "%"); 
      JSONObject windInfo = result.getJSONObject("wind"); 
      wind.setText(windInfo.getString("speed") + "m/s"); 
      JSONArray weatherArray = result.getJSONArray("weather"); 
      JSONObject weather = weatherArray.getJSONObject(0); 
      desc.setText(weather.getString("main")); 
     } if (result.getInt("cod") == 404) { 
      Toast.makeText(mContext, "Location not found", Toast.LENGTH_SHORT).show(); 
     } 
    } catch (JSONException e) { 
     e.printStackTrace(); 
    } 
} 

}

CurrentWeatherUpdater cwu; объявлен в MainActivity.java

В принципе, когда я называю CurrentWeatherUpdater(this) конструктор из onOptionsItemSelected он работает отлично. Но когда я называю его от doSearch, хотя context указывает на MainActivity так же, как в другом, ни одно из полей (city, temp и т.д.) не присваивается значение и updateView метод идет вниз в пламени с NullPointerException на this.city.setText(result.getString("name"))

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference 

Даже когда он впервые вызывается из onOptionsItemSelected и CurrentWeatherUpdater cwu объект должен быть уже создан if (this.cwu == null) вычисляется в true и создается новый объект.

+0

вместо литья 'Активность', попробуйте' MainActivity' – adnbsr

+0

Спасибо за ваше предложение, но это не решило его. – dgabka95

+0

попробуйте 'city' вместо' this.city' – W4R10CK

ответ

0

Вы можете использовать LocalBroadcastManager транслировать данные в другой класс

Вы можете установить данные в LocalBroadcastManager по

Intent intent = new Intent("myFunction"); 
       // add data 
       intent.putExtra("variable1", "Data1"); 
       intent.putExtra("variable2", "Data2"); 
       intent.putExtra("variable3", "Data3"); 
       LocalBroadcastManager.getInstance(this).sendBroadcast(intent); 

И теперь в классе, где взгляды обновления определяются в поставить этот код:

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      // Extract data included in the Intent 
      String t = intent.getStringExtra("variable1"); 
      String t1 = intent.getStringExtra("variable2"); 
      String t2 = intent.getStringExtra("variable3"); 
      //Updating textview function 
      updateTheTextView(t, t1, t2); 
     } 
    }; 
    @Override 
    public void onResume() { 
     super.onResume(); 
     LocalBroadcastManager.getInstance(this.getActivity()).registerReceiver(mMessageReceiver, 
       new IntentFilter("myFunction")); 
    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
     LocalBroadcastManager.getInstance(this.getActivity()).unregisterReceiver(mMessageReceiver); 
    } 

Я не уверен, поможет ли это вам! Но так мне удалось отправить данные в texviews, определенные в другом классе.